blob: dc408ca5e71d905913a70d98ead45c7a48f13e92 [file] [log] [blame]
David Burger7fd1dbe2020-03-26 09:26:55 -06001#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright 2020 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6"""Transforms config from /config/proto/api proto format to platform JSON."""
7
Ren-Pei Zengce869dd2020-08-18 01:29:37 +08008# pylint: disable=too-many-lines
9
David Burger7fd1dbe2020-03-26 09:26:55 -060010import argparse
11import json
12import pprint
C Shapiro90fda252020-04-17 14:34:57 -050013import os
David Burger7fd1dbe2020-03-26 09:26:55 -060014import sys
C Shapiro90fda252020-04-17 14:34:57 -050015import re
C Shapiro5bf23a72020-04-24 11:40:17 -050016import xml.etree.ElementTree as etree
C Shapiro9a3ac8c2020-04-25 07:49:21 -050017import xml.dom.minidom as minidom
David Burger7fd1dbe2020-03-26 09:26:55 -060018
Andrew Lamb319cc922020-06-15 10:45:46 -060019from typing import List
20
David Burger7fd1dbe2020-03-26 09:26:55 -060021from collections import namedtuple
22
Andrew Lambcd33f702020-06-11 10:45:16 -060023from google.protobuf import json_format
24
Prathmesh Prabhu72f8a002020-04-10 09:57:53 -070025from chromiumos.config.api import device_brand_pb2
David Burger92609a32020-04-23 10:38:50 -060026from chromiumos.config.api import topology_pb2
C Shapiro5bf23a72020-04-24 11:40:17 -050027from chromiumos.config.payload import config_bundle_pb2
Prathmesh Prabhu72f8a002020-04-10 09:57:53 -070028from chromiumos.config.api.software import brand_config_pb2
David Burger7fd1dbe2020-03-26 09:26:55 -060029
Andrew Lamb2413c982020-05-29 12:15:36 -060030Config = namedtuple('Config', [
31 'program', 'hw_design', 'odm', 'hw_design_config', 'device_brand',
32 'device_signer_config', 'oem', 'sw_config', 'brand_config', 'build_target'
33])
David Burger7fd1dbe2020-03-26 09:26:55 -060034
David Burger07af5242020-08-11 11:08:25 -060035ConfigFiles = namedtuple(
David Burgerdd3c1272020-08-24 12:45:03 -060036 'ConfigFiles', ['arc_hw_features', 'touch_fw', 'dptf_map', 'camera_map'])
David Burger8ee9b4d2020-06-16 17:40:21 -060037
38CAMERA_CONFIG_DEST_PATH_TEMPLATE = '/etc/camera/camera_config_{}.json'
39CAMERA_CONFIG_SOURCE_PATH_TEMPLATE = (
40 'sw_build_config/platform/chromeos-config/camera/camera_config_{}.json')
C Shapiro5bf23a72020-04-24 11:40:17 -050041
David Burger52c9d322020-06-09 07:16:18 -060042DPTF_PATH = 'sw_build_config/platform/chromeos-config/thermal'
43DPTF_FILE = 'dptf.dv'
David Burger2f0d9522020-07-30 10:52:28 -060044
C Shapiro2b6d5332020-05-06 17:51:35 -050045TOUCH_PATH = 'sw_build_config/platform/chromeos-config/touch'
Andrew Lamb6c42efc2020-06-16 10:40:43 -060046WALLPAPER_BASE_PATH = '/usr/share/chromeos-assets/wallpaper'
David Burger7fd1dbe2020-03-26 09:26:55 -060047
Andrew Lamb2413c982020-05-29 12:15:36 -060048
Andrew Lambcd33f702020-06-11 10:45:16 -060049def parse_args(argv):
David Burger7fd1dbe2020-03-26 09:26:55 -060050 """Parse the available arguments.
51
52 Invalid arguments or -h cause this function to print a message and exit.
53
54 Args:
55 argv: List of string arguments (excluding program name / argv[0])
56
57 Returns:
58 argparse.Namespace object containing the attributes.
59 """
60 parser = argparse.ArgumentParser(
61 description='Converts source proto config into platform JSON config.')
62 parser.add_argument(
63 '-c',
64 '--project_configs',
65 nargs='+',
66 type=str,
67 help='Space delimited list of source protobinary project config files.')
68 parser.add_argument(
69 '-p',
70 '--program_config',
71 type=str,
72 help='Path to the source program-level protobinary file')
73 parser.add_argument(
Andrew Lamb2413c982020-05-29 12:15:36 -060074 '-o', '--output', type=str, help='Output file that will be generated')
David Burger7fd1dbe2020-03-26 09:26:55 -060075 return parser.parse_args(argv)
76
77
David Burger8ee9b4d2020-06-16 17:40:21 -060078def _upsert(field, target, target_name):
79 """Updates or inserts `field` within `target`.
80
81 If `target_name` already exists within `target` an update is performed,
82 otherwise, an insert is performed.
83 """
Sam McNally9a873f72020-06-05 19:47:22 +100084 if field or field == 0:
David Burger8ee9b4d2020-06-16 17:40:21 -060085 if target_name in target:
86 target[target_name].update(field)
87 else:
88 target[target_name] = field
David Burger7fd1dbe2020-03-26 09:26:55 -060089
90
Andrew Lambcd33f702020-06-11 10:45:16 -060091def _build_arc(config, config_files):
92 if not config.build_target.arc:
93 return None
94
95 build_properties = {
96 'device': config.build_target.arc.device,
97 'first-api-level': config.build_target.arc.first_api_level,
98 'marketing-name': config.device_brand.brand_name,
99 'metrics-tag': config.hw_design.name.lower(),
100 'product': config.build_target.id.value,
101 }
102 if config.oem:
103 build_properties['oem'] = config.oem.name
104 result = {'build-properties': build_properties}
105 feature_id = _arc_hardware_feature_id(config.hw_design_config)
106 if feature_id in config_files.arc_hw_features:
107 result['hardware-features'] = config_files.arc_hw_features[feature_id]
108 topology = config.hw_design_config.hardware_topology
109 ppi = topology.screen.hardware_feature.screen.panel_properties.pixels_per_in
110 # Only set for high resolution displays
111 if ppi and ppi > 250:
112 result['scale'] = ppi
David Burger2f0d9522020-07-30 10:52:28 -0600113
Andrew Lambcd33f702020-06-11 10:45:16 -0600114 return result
David Burger7fd1dbe2020-03-26 09:26:55 -0600115
Andrew Lamb2413c982020-05-29 12:15:36 -0600116
Andrew Lamb319cc922020-06-15 10:45:46 -0600117def _build_ash_flags(config: Config) -> List[str]:
118 """Returns a list of Ash flags for config.
119
120 Ash is the window manager and system UI for ChromeOS, see
121 https://chromium.googlesource.com/chromium/src/+/refs/heads/master/ash/.
122 """
123 # A map from flag name -> value. Value may be None for boolean flags.
124 flags = {}
125
126 hw_features = config.hw_design_config.hardware_features
127 if hw_features.stylus.stylus == topology_pb2.HardwareFeatures.Stylus.INTERNAL:
Andrew Lamb2e641e22020-06-15 12:30:41 -0600128 flags['has-internal-stylus'] = None
Andrew Lamb319cc922020-06-15 10:45:46 -0600129
Andrew Lamb2e641e22020-06-15 12:30:41 -0600130 fp_loc = hw_features.fingerprint.location
131 if fp_loc and fp_loc != topology_pb2.HardwareFeatures.Fingerprint.NOT_PRESENT:
132 loc_name = topology_pb2.HardwareFeatures.Fingerprint.Location.Name(fp_loc)
133 flags['fingerprint-sensor-location'] = loc_name.lower().replace('_', '-')
134
Andrew Lamb6c42efc2020-06-16 10:40:43 -0600135 wallpaper = config.brand_config.wallpaper
136 # If a wallpaper is set, the 'default-wallpaper-is-oem' flag needs to be set.
137 # If a wallpaper is not set, the 'default_[large|small].jpg' wallpapers
138 # should still be set.
139 if wallpaper:
140 flags['default-wallpaper-is-oem'] = None
141 else:
142 wallpaper = 'default'
143
144 for size in ('small', 'large'):
145 flags[f'default-wallpaper-{size}'] = (
146 f'{WALLPAPER_BASE_PATH}/{wallpaper}_{size}.jpg')
147
148 # For each size, also install 'guest' and 'child' wallpapers.
149 for wallpaper_type in ('guest', 'child'):
150 flags[f'{wallpaper_type}-wallpaper-{size}'] = (
151 f'{WALLPAPER_BASE_PATH}/{wallpaper_type}_{size}.jpg')
152
Andrew Lamb72d41362020-06-17 09:19:02 -0600153 flags['arc-build-properties'] = json_format.MessageToDict(
154 config.build_target.arc)
155
Andrew Lamb90b168c2020-06-22 10:42:30 -0600156 power_button = hw_features.power_button
157 if power_button.edge:
158 flags['ash-power-button-position'] = json.dumps({
159 'edge':
160 topology_pb2.HardwareFeatures.Button.Edge.Name(power_button.edge
161 ).lower(),
162 # Starlark sometimes represents float literals strangely, e.g. changing
163 # 0.9 to 0.899999. Round to two digits here.
164 'position':
165 round(power_button.position, 2)
166 })
167
168 volume_button = hw_features.volume_button
169 if volume_button.edge:
170 flags['ash-side-volume-button-position'] = json.dumps({
171 'region':
172 topology_pb2.HardwareFeatures.Button.Region.Name(
173 volume_button.region).lower(),
174 'edge':
175 topology_pb2.HardwareFeatures.Button.Edge.Name(volume_button.edge
176 ).lower(),
177 })
178
Andrew Lamb2e641e22020-06-15 12:30:41 -0600179 return sorted([f'--{k}={v}' if v else f'--{k}' for k, v in flags.items()])
Andrew Lamb319cc922020-06-15 10:45:46 -0600180
181
182def _build_ui(config: Config) -> dict:
183 """Builds the 'ui' property from cros_config_schema."""
184 return {'extra-ash-flags': _build_ash_flags(config)}
185
186
David Burger07af5242020-08-11 11:08:25 -0600187def _build_bluetooth(config):
C Shapiro90fda252020-04-17 14:34:57 -0500188 bt_flags = config.sw_config.bluetooth_config.flags
189 # Convert to native map (from proto wrapper)
190 bt_flags_map = dict(bt_flags)
191 result = {}
192 if bt_flags_map:
193 result['flags'] = bt_flags_map
C Shapiro90fda252020-04-17 14:34:57 -0500194 return result
195
David Burger7fd1dbe2020-03-26 09:26:55 -0600196
David Burgerec753912020-08-10 12:59:11 -0600197def _build_wifi(config):
198 result = {}
199 if config.sw_config.wifi_config.HasField('ath10k_config'):
200 ath10k_config = config.sw_config.wifi_config.ath10k_config
201
202 def power_chain(power):
203 return {
204 'limit-2g': power.limit_2g,
205 'limit-5g': power.limit_5g,
206 }
207
208 result['tablet-mode-power-table-ath10k'] = power_chain(
209 ath10k_config.tablet_mode_power_table)
210 result['non-tablet-mode-power-table-ath10k'] = power_chain(
211 ath10k_config.non_tablet_mode_power_table)
212 elif config.sw_config.wifi_config.HasField('rtw88_config'):
213 rtw88_config = config.sw_config.wifi_config.rtw88_config
214
215 def power_chain(power):
216 return {
217 'limit-2g': power.limit_2g,
218 'limit-5g-1': power.limit_5g_1,
219 'limit-5g-3': power.limit_5g_3,
220 'limit-5g-4': power.limit_5g_4,
221 }
222
223 result['tablet-mode-power-table-rtw'] = power_chain(
224 rtw88_config.tablet_mode_power_table)
225 result['non-tablet-mode-power-table-rtw'] = power_chain(
226 rtw88_config.non_tablet_mode_power_table)
227
228 def offsets(offset):
229 return {
230 'offset-2g': offset.offset_2g,
231 'offset-5g': offset.offset_5g,
232 }
233
234 result['geo-offsets-fcc'] = offsets(rtw88_config.offset_fcc)
235 result['geo-offsets-eu'] = offsets(rtw88_config.offset_eu)
236 result['geo-offsets-rest-of-world'] = offsets(rtw88_config.offset_other)
237 return result
238
239
Andrew Lambcd33f702020-06-11 10:45:16 -0600240def _build_fingerprint(hw_topology):
241 if not hw_topology.HasField('fingerprint'):
242 return None
243
244 fp = hw_topology.fingerprint.hardware_feature.fingerprint
245 result = {}
246 if fp.location != topology_pb2.HardwareFeatures.Fingerprint.NOT_PRESENT:
247 location = fp.Location.DESCRIPTOR.values_by_number[fp.location].name
248 result['sensor-location'] = location.lower().replace('_', '-')
249 if fp.board:
250 result['board'] = fp.board
Tom Hughesdfc35402020-06-29 16:02:09 -0700251 if fp.ro_version:
252 result['ro-version'] = fp.ro_version
253
Andrew Lambcd33f702020-06-11 10:45:16 -0600254 return result
David Burger7fd1dbe2020-03-26 09:26:55 -0600255
256
Trent Beginf067ccb2020-08-12 12:33:53 -0600257def _build_hardware_properties(hw_topology):
258 if not hw_topology.HasField('form_factor'):
259 return None
260
261 form_factor = hw_topology.form_factor.hardware_feature.form_factor.form_factor
262 result = {}
263 if form_factor in [
264 topology_pb2.HardwareFeatures.FormFactor.CHROMEBIT,
265 topology_pb2.HardwareFeatures.FormFactor.CHROMEBASE,
266 topology_pb2.HardwareFeatures.FormFactor.CHROMEBOX
267 ]:
268 result['psu-type'] = "AC_only"
269 else:
270 result['psu-type'] = "battery"
271
272 result['has-backlight'] = form_factor not in [
273 topology_pb2.HardwareFeatures.FormFactor.CHROMEBIT,
274 topology_pb2.HardwareFeatures.FormFactor.CHROMEBOX
275 ]
276
277 return result
278
279
Andrew Lambcd33f702020-06-11 10:45:16 -0600280def _fw_bcs_path(payload):
David Burger7fd1dbe2020-03-26 09:26:55 -0600281 if payload and payload.firmware_image_name:
Andrew Lamb2413c982020-05-29 12:15:36 -0600282 return 'bcs://%s.%d.%d.0.tbz2' % (payload.firmware_image_name,
283 payload.version.major,
284 payload.version.minor)
David Burger7fd1dbe2020-03-26 09:26:55 -0600285
Andrew Lambcd33f702020-06-11 10:45:16 -0600286 return None
David Burger7fd1dbe2020-03-26 09:26:55 -0600287
Andrew Lambcd33f702020-06-11 10:45:16 -0600288
289def _fw_build_target(payload):
David Burger7fd1dbe2020-03-26 09:26:55 -0600290 if payload:
291 return payload.build_target_name
292
Andrew Lambcd33f702020-06-11 10:45:16 -0600293 return None
David Burger7fd1dbe2020-03-26 09:26:55 -0600294
Andrew Lambcd33f702020-06-11 10:45:16 -0600295
296def _build_firmware(config):
David Burgerb70b6762020-05-21 12:14:59 -0600297 """Returns firmware config, or None if no build targets."""
Andrew Lamb3da156d2020-04-16 16:00:56 -0600298 fw_payload_config = config.sw_config.firmware
299 fw_build_config = config.sw_config.firmware_build_config
300 main_ro = fw_payload_config.main_ro_payload
301 main_rw = fw_payload_config.main_rw_payload
302 ec_ro = fw_payload_config.ec_ro_payload
303 pd_ro = fw_payload_config.pd_ro_payload
David Burger7fd1dbe2020-03-26 09:26:55 -0600304
305 build_targets = {}
Andrew Lamb3da156d2020-04-16 16:00:56 -0600306
David Burger8ee9b4d2020-06-16 17:40:21 -0600307 _upsert(fw_build_config.build_targets.depthcharge, build_targets,
308 'depthcharge')
309 _upsert(fw_build_config.build_targets.coreboot, build_targets, 'coreboot')
310 _upsert(fw_build_config.build_targets.ec, build_targets, 'ec')
311 _upsert(
Andrew Lambf8954ee2020-04-21 10:24:40 -0600312 list(fw_build_config.build_targets.ec_extras), build_targets, 'ec_extras')
David Burger8ee9b4d2020-06-16 17:40:21 -0600313 _upsert(fw_build_config.build_targets.libpayload, build_targets, 'libpayload')
David Burger7fd1dbe2020-03-26 09:26:55 -0600314
David Burgerb70b6762020-05-21 12:14:59 -0600315 if not build_targets:
316 return None
317
David Burger7fd1dbe2020-03-26 09:26:55 -0600318 result = {
319 'bcs-overlay': config.build_target.overlay_name,
320 'build-targets': build_targets,
David Burger7fd1dbe2020-03-26 09:26:55 -0600321 }
Andrew Lamb883fa042020-04-06 11:37:22 -0600322
David Burger8ee9b4d2020-06-16 17:40:21 -0600323 _upsert(main_ro.firmware_image_name.lower(), result, 'image-name')
Andrew Lamb883fa042020-04-06 11:37:22 -0600324
David Burger8ee9b4d2020-06-16 17:40:21 -0600325 _upsert(_fw_bcs_path(main_ro), result, 'main-ro-image')
326 _upsert(_fw_bcs_path(main_rw), result, 'main-rw-image')
327 _upsert(_fw_bcs_path(ec_ro), result, 'ec-ro-image')
328 _upsert(_fw_bcs_path(pd_ro), result, 'pd-ro-image')
David Burger7fd1dbe2020-03-26 09:26:55 -0600329
David Burger8ee9b4d2020-06-16 17:40:21 -0600330 _upsert(
Andrew Lambf39fbe82020-04-13 16:14:33 -0600331 config.hw_design_config.hardware_features.fw_config.value,
332 result,
333 'firmware-config',
334 )
335
David Burger7fd1dbe2020-03-26 09:26:55 -0600336 return result
337
338
Andrew Lambcd33f702020-06-11 10:45:16 -0600339def _build_fw_signing(config):
C Shapiro2f0bb5d2020-04-14 10:07:47 -0500340 if config.sw_config.firmware and config.device_signer_config:
David Burger68e0d142020-05-15 17:29:33 -0600341 hw_design = config.hw_design.name.lower()
Sam McNally2fc807f2020-07-16 18:13:53 +1000342 brand_scan_config = config.brand_config.scan_config
343 if brand_scan_config and brand_scan_config.whitelabel_tag:
344 signature_id = '%s-%s' % (hw_design, brand_scan_config.whitelabel_tag)
345 else:
346 signature_id = hw_design
347
C Shapiro2f0bb5d2020-04-14 10:07:47 -0500348 return {
349 'key-id': config.device_signer_config.key_id,
Sam McNally2fc807f2020-07-16 18:13:53 +1000350 'signature-id': signature_id,
C Shapiro2f0bb5d2020-04-14 10:07:47 -0500351 }
352 return {}
David Burger7fd1dbe2020-03-26 09:26:55 -0600353
354
Andrew Lambcd33f702020-06-11 10:45:16 -0600355def _file(source, destination):
Andrew Lamb2413c982020-05-29 12:15:36 -0600356 return {'destination': destination, 'source': source}
David Burger7fd1dbe2020-03-26 09:26:55 -0600357
358
David Burger40dfe3a2020-06-18 17:09:13 -0600359def _file_v2(build_path, system_path):
360 return {'build-path': build_path, 'system-path': system_path}
361
362
Andrew Lambcd33f702020-06-11 10:45:16 -0600363def _build_audio(config):
David Burger178f3ef2020-06-26 12:11:57 -0600364 if not config.sw_config.audio_configs:
365 return {}
David Burger7fd1dbe2020-03-26 09:26:55 -0600366 alsa_path = '/usr/share/alsa/ucm'
367 cras_path = '/etc/cras'
368 project_name = config.hw_design.name.lower()
David Burger43250662020-05-07 11:21:50 -0600369 program_name = config.program.name.lower()
David Burger7fd1dbe2020-03-26 09:26:55 -0600370 files = []
David Burger178f3ef2020-06-26 12:11:57 -0600371 ucm_suffix = None
372 for audio in config.sw_config.audio_configs:
373 card = audio.card_name
374 card_with_suffix = audio.card_name
375 if audio.ucm_suffix:
376 # TODO: last ucm_suffix wins.
377 ucm_suffix = audio.ucm_suffix
378 card_with_suffix += '.' + audio.ucm_suffix
379 if audio.ucm_file:
380 files.append(
381 _file(audio.ucm_file,
382 '%s/%s/HiFi.conf' % (alsa_path, card_with_suffix)))
383 if audio.ucm_master_file:
384 files.append(
385 _file(
386 audio.ucm_master_file, '%s/%s/%s.conf' %
Andrew Lamb2413c982020-05-29 12:15:36 -0600387 (alsa_path, card_with_suffix, card_with_suffix)))
David Burger178f3ef2020-06-26 12:11:57 -0600388 if audio.card_config_file:
389 files.append(
390 _file(audio.card_config_file,
391 '%s/%s/%s' % (cras_path, project_name, card)))
392 if audio.dsp_file:
393 files.append(
394 _file(audio.dsp_file, '%s/%s/dsp.ini' % (cras_path, project_name)))
395 if audio.module_file:
396 files.append(
397 _file(audio.module_file,
398 '/etc/modprobe.d/alsa-%s.conf' % program_name))
399 if audio.board_file:
400 files.append(
401 _file(audio.board_file,
402 '%s/%s/board.ini' % (cras_path, project_name)))
David Burger599ff7b2020-04-06 16:29:31 -0600403
404 result = {
David Burger7fd1dbe2020-03-26 09:26:55 -0600405 'main': {
406 'cras-config-dir': project_name,
407 'files': files,
408 }
409 }
David Burger178f3ef2020-06-26 12:11:57 -0600410
411 if ucm_suffix:
412 result['main']['ucm-suffix'] = ucm_suffix
David Burger599ff7b2020-04-06 16:29:31 -0600413
414 return result
David Burger7fd1dbe2020-03-26 09:26:55 -0600415
416
Andrew Lambcd33f702020-06-11 10:45:16 -0600417def _build_camera(hw_topology):
David Burger8aa8fa32020-04-14 08:30:34 -0600418 if hw_topology.HasField('camera'):
Ren-Pei Zengce869dd2020-08-18 01:29:37 +0800419 camera_pb = topology_pb2.HardwareFeatures.Camera
David Burger8aa8fa32020-04-14 08:30:34 -0600420 camera = hw_topology.camera.hardware_feature.camera
421 result = {}
422 if camera.count.value:
423 result['count'] = camera.count.value
Ren-Pei Zengce869dd2020-08-18 01:29:37 +0800424 if camera.devices:
425 result['devices'] = []
426 for device in camera.devices:
427 interface = {
428 camera_pb.INTERFACE_USB: 'usb',
429 camera_pb.INTERFACE_MIPI: 'mipi',
430 }[device.interface]
431 facing = {
432 camera_pb.FACING_FRONT: 'front',
433 camera_pb.FACING_BACK: 'back',
434 }[device.facing]
435 orientation = {
436 camera_pb.ORIENTATION_0: 0,
437 camera_pb.ORIENTATION_90: 90,
438 camera_pb.ORIENTATION_180: 180,
439 camera_pb.ORIENTATION_270: 270,
440 }[device.orientation]
441 result['devices'].append({
442 'id': device.id,
443 'interface': interface,
444 'facing': facing,
445 'orientation': orientation,
446 })
David Burger8aa8fa32020-04-14 08:30:34 -0600447 return result
448
Andrew Lambcd33f702020-06-11 10:45:16 -0600449 return None
David Burger8aa8fa32020-04-14 08:30:34 -0600450
Andrew Lambcd33f702020-06-11 10:45:16 -0600451
452def _build_identity(hw_scan_config, program, brand_scan_config=None):
David Burger7fd1dbe2020-03-26 09:26:55 -0600453 identity = {}
David Burger8ee9b4d2020-06-16 17:40:21 -0600454 _upsert(hw_scan_config.firmware_sku, identity, 'sku-id')
455 _upsert(hw_scan_config.smbios_name_match, identity, 'smbios-name-match')
Andrew Lamb7806ce92020-04-07 10:22:17 -0600456 # 'platform-name' is needed to support 'mosys platform name'. Clients should
457 # longer require platform name, but set it here for backwards compatibility.
David Burger8ee9b4d2020-06-16 17:40:21 -0600458 _upsert(program.name, identity, 'platform-name')
David Burger7fd1dbe2020-03-26 09:26:55 -0600459 # ARM architecture
David Burger8ee9b4d2020-06-16 17:40:21 -0600460 _upsert(hw_scan_config.device_tree_compatible_match, identity,
461 'device-tree-compatible-match')
David Burger7fd1dbe2020-03-26 09:26:55 -0600462
463 if brand_scan_config:
David Burger8ee9b4d2020-06-16 17:40:21 -0600464 _upsert(brand_scan_config.whitelabel_tag, identity, 'whitelabel-tag')
David Burger7fd1dbe2020-03-26 09:26:55 -0600465
466 return identity
467
468
Andrew Lambcd33f702020-06-11 10:45:16 -0600469def _lookup(id_value, id_map):
470 if not id_value.value:
471 return None
472
473 key = id_value.value
474 if key in id_map:
475 return id_map[id_value.value]
476 error = 'Failed to lookup %s with value: %s' % (
477 id_value.__class__.__name__.replace('Id', ''), key)
478 print(error)
479 print('Check the config contents provided:')
480 printer = pprint.PrettyPrinter(indent=4)
481 printer.pprint(id_map)
482 raise Exception(error)
David Burger7fd1dbe2020-03-26 09:26:55 -0600483
484
Andrew Lambcd33f702020-06-11 10:45:16 -0600485def _build_touch_file_config(config, project_name):
Sean McAllistereaf10b72020-08-03 13:41:06 -0600486 partners = {x.id.value: x for x in config.partner_list}
C Shapiro2b6d5332020-05-06 17:51:35 -0500487 files = []
488 for comp in config.components:
C Shapiro4813be62020-05-13 17:31:58 -0500489 touch = comp.touchscreen
490 # Everything is the same for Touch screen/pad, except different fields
491 if comp.HasField('touchpad'):
492 touch = comp.touchpad
493 if touch.product_id:
Andrew Lambcd33f702020-06-11 10:45:16 -0600494 vendor = _lookup(comp.manufacturer_id, partners)
C Shapiro2b6d5332020-05-06 17:51:35 -0500495 if not vendor:
Andrew Lamb2413c982020-05-29 12:15:36 -0600496 raise Exception("Manufacturer must be set for touch device %s" %
497 comp.id.value)
C Shapiro2b6d5332020-05-06 17:51:35 -0500498
C Shapiro4813be62020-05-13 17:31:58 -0500499 product_id = touch.product_id
500 fw_version = touch.fw_version
C Shapiro2b6d5332020-05-06 17:51:35 -0500501
C Shapiro2b6d5332020-05-06 17:51:35 -0500502 file_name = "%s_%s.bin" % (product_id, fw_version)
503 fw_file_path = os.path.join(TOUCH_PATH, vendor.name, file_name)
504
505 if not os.path.exists(fw_file_path):
Andrew Lamb2413c982020-05-29 12:15:36 -0600506 raise Exception("Touchscreen fw bin file doesn't exist at: %s" %
507 fw_file_path)
C Shapiro2b6d5332020-05-06 17:51:35 -0500508
C Shapiro303cece2020-07-22 07:15:21 -0500509 touch_vendor = vendor.touch_vendor
510 sym_link = touch_vendor.symlink_file_format.format(
511 vendor_name=vendor.name,
512 vendor_id=touch_vendor.vendor_id,
513 product_id=product_id,
514 fw_version=fw_version,
515 product_series=touch.product_series)
516
517 dest = "%s_%s" % (vendor.name, file_name)
518 if touch_vendor.destination_file_format:
519 dest = touch_vendor.destination_file_format.format(
520 vendor_name=vendor.name,
521 vendor_id=touch_vendor.vendor_id,
522 product_id=product_id,
523 fw_version=fw_version,
524 product_series=touch.product_series)
525
C Shapiro2b6d5332020-05-06 17:51:35 -0500526 files.append({
C Shapiro303cece2020-07-22 07:15:21 -0500527 "destination": os.path.join("/opt/google/touch/firmware", dest),
YH Lin9160fc52020-07-22 16:35:28 -0700528 "source": os.path.join(project_name, fw_file_path),
529 "symlink": os.path.join("/lib/firmware", sym_link),
C Shapiro2b6d5332020-05-06 17:51:35 -0500530 })
531
532 result = {}
David Burger8ee9b4d2020-06-16 17:40:21 -0600533 _upsert(files, result, 'files')
C Shapiro2b6d5332020-05-06 17:51:35 -0500534 return result
535
536
David Burgerdd3c1272020-08-24 12:45:03 -0600537def _transform_build_configs(config, config_files=ConfigFiles({}, {}, {}, {})):
Andrew Lambcd33f702020-06-11 10:45:16 -0600538 # pylint: disable=too-many-locals,too-many-branches
Sean McAllistereaf10b72020-08-03 13:41:06 -0600539 partners = {x.id.value: x for x in config.partner_list}
Sean McAllisterf38d1e92020-08-03 13:57:53 -0600540 programs = {x.id.value: x for x in config.program_list}
David Burger7fd1dbe2020-03-26 09:26:55 -0600541 sw_configs = list(config.software_configs)
Andrew Lambcd33f702020-06-11 10:45:16 -0600542 brand_configs = {x.brand_id.value: x for x in config.brand_configs}
David Burger7fd1dbe2020-03-26 09:26:55 -0600543
C Shapiroa0b766c2020-03-31 08:35:28 -0500544 if len(config.build_targets) != 1:
545 # Artifact of sharing the config_bundle for analysis and transforms.
546 # Integrated analysis of multiple programs/projects it the only time
547 # having multiple build targets would be valid.
548 raise Exception('Single build_target required for transform')
549
David Burger7fd1dbe2020-03-26 09:26:55 -0600550 results = {}
Sean McAllisterf66887b2020-08-03 14:00:51 -0600551 for hw_design in config.design_list:
Sean McAllister6cbb0ec2020-08-03 14:03:37 -0600552 if config.device_brand_list:
Andrew Lamb2413c982020-05-29 12:15:36 -0600553 device_brands = [
Sean McAllister6cbb0ec2020-08-03 14:03:37 -0600554 x for x in config.device_brand_list
Andrew Lamb2413c982020-05-29 12:15:36 -0600555 if x.design_id.value == hw_design.id.value
556 ]
David Burger7fd1dbe2020-03-26 09:26:55 -0600557 else:
558 device_brands = [device_brand_pb2.DeviceBrand()]
559
560 for device_brand in device_brands:
561 # Brand config can be empty since platform JSON config allows it
562 brand_config = brand_config_pb2.BrandConfig()
563 if device_brand.id.value in brand_configs:
564 brand_config = brand_configs[device_brand.id.value]
565
566 for hw_design_config in hw_design.configs:
567 design_id = hw_design_config.id.value
Andrew Lamb2413c982020-05-29 12:15:36 -0600568 sw_config_matches = [
569 x for x in sw_configs if x.design_config_id.value == design_id
570 ]
David Burger7fd1dbe2020-03-26 09:26:55 -0600571 if len(sw_config_matches) == 1:
572 sw_config = sw_config_matches[0]
573 elif len(sw_config_matches) > 1:
574 raise Exception('Multiple software configs found for: %s' % design_id)
575 else:
576 raise Exception('Software config is required for: %s' % design_id)
577
Andrew Lambcd33f702020-06-11 10:45:16 -0600578 program = _lookup(hw_design.program_id, programs)
C Shapiroadefd7c2020-05-19 16:37:21 -0500579 signer_configs_by_design = {}
580 signer_configs_by_brand = {}
581 for signer_config in program.device_signer_configs:
582 design_id = signer_config.design_id.value
583 brand_id = signer_config.brand_id.value
584 if design_id:
585 signer_configs_by_design[design_id] = signer_config
586 elif brand_id:
587 signer_configs_by_brand[brand_id] = signer_config
588 else:
589 raise Exception('No ID found for signer config: %s' % signer_config)
590
C Shapiro2f0bb5d2020-04-14 10:07:47 -0500591 device_signer_config = None
C Shapiroadefd7c2020-05-19 16:37:21 -0500592 if signer_configs_by_design or signer_configs_by_brand:
593 design_id = hw_design.id.value
594 brand_id = device_brand.id.value
595 if design_id in signer_configs_by_design:
596 device_signer_config = signer_configs_by_design[design_id]
597 elif brand_id in signer_configs_by_brand:
598 device_signer_config = signer_configs_by_brand[brand_id]
599 else:
600 # Assume that if signer configs are set, every config is setup
Andrew Lamb2413c982020-05-29 12:15:36 -0600601 raise Exception('Signer config missing for design: %s, brand: %s' %
602 (design_id, brand_id))
C Shapiro2f0bb5d2020-04-14 10:07:47 -0500603
Andrew Lambcd33f702020-06-11 10:45:16 -0600604 transformed_config = _transform_build_config(
C Shapiro90fda252020-04-17 14:34:57 -0500605 Config(
606 program=program,
607 hw_design=hw_design,
Andrew Lambcd33f702020-06-11 10:45:16 -0600608 odm=_lookup(hw_design.odm_id, partners),
C Shapiro90fda252020-04-17 14:34:57 -0500609 hw_design_config=hw_design_config,
610 device_brand=device_brand,
611 device_signer_config=device_signer_config,
Andrew Lambcd33f702020-06-11 10:45:16 -0600612 oem=_lookup(device_brand.oem_id, partners),
C Shapiro90fda252020-04-17 14:34:57 -0500613 sw_config=sw_config,
614 brand_config=brand_config,
Andrew Lamb2413c982020-05-29 12:15:36 -0600615 build_target=config.build_targets[0]), config_files)
David Burger7fd1dbe2020-03-26 09:26:55 -0600616
Andrew Lamb2413c982020-05-29 12:15:36 -0600617 config_json = json.dumps(
618 transformed_config,
619 sort_keys=True,
620 indent=2,
621 separators=(',', ': '))
David Burger7fd1dbe2020-03-26 09:26:55 -0600622
623 if config_json not in results:
624 results[config_json] = transformed_config
625
626 return list(results.values())
627
628
Andrew Lambcd33f702020-06-11 10:45:16 -0600629def _transform_build_config(config, config_files):
David Burger7fd1dbe2020-03-26 09:26:55 -0600630 """Transforms Config instance into target platform JSON schema.
631
632 Args:
633 config: Config namedtuple
C Shapiro5bf23a72020-04-24 11:40:17 -0500634 config_files: Map to look up the generated config files.
David Burger7fd1dbe2020-03-26 09:26:55 -0600635
636 Returns:
637 Unique config payload based on the platform JSON schema.
638 """
639 result = {
Andrew Lamb2413c982020-05-29 12:15:36 -0600640 'identity':
Andrew Lambcd33f702020-06-11 10:45:16 -0600641 _build_identity(config.sw_config.id_scan_config, config.program,
642 config.brand_config.scan_config),
Andrew Lamb2413c982020-05-29 12:15:36 -0600643 'name':
644 config.hw_design.name.lower(),
David Burger7fd1dbe2020-03-26 09:26:55 -0600645 }
646
David Burger8ee9b4d2020-06-16 17:40:21 -0600647 _upsert(_build_arc(config, config_files), result, 'arc')
648 _upsert(_build_audio(config), result, 'audio')
David Burger07af5242020-08-11 11:08:25 -0600649 _upsert(_build_bluetooth(config), result, 'bluetooth')
David Burgerec753912020-08-10 12:59:11 -0600650 _upsert(_build_wifi(config), result, 'wifi')
Andrew Lambca279902020-08-06 10:13:42 -0600651 _upsert(config.brand_config.wallpaper, result, 'wallpaper')
David Burger8ee9b4d2020-06-16 17:40:21 -0600652 _upsert(config.device_brand.brand_code, result, 'brand-code')
653 _upsert(
Andrew Lambcd33f702020-06-11 10:45:16 -0600654 _build_camera(config.hw_design_config.hardware_topology), result,
655 'camera')
David Burger8ee9b4d2020-06-16 17:40:21 -0600656 _upsert(_build_firmware(config), result, 'firmware')
657 _upsert(_build_fw_signing(config), result, 'firmware-signing')
658 _upsert(
Andrew Lambcd33f702020-06-11 10:45:16 -0600659 _build_fingerprint(config.hw_design_config.hardware_topology), result,
Andrew Lamb2413c982020-05-29 12:15:36 -0600660 'fingerprint')
Andrew Lamb0d236ab2020-06-30 12:30:20 -0600661 _upsert(_build_ui(config), result, 'ui')
David Burger7fd1dbe2020-03-26 09:26:55 -0600662 power_prefs = config.sw_config.power_config.preferences
663 power_prefs_map = dict(
Andrew Lamb2413c982020-05-29 12:15:36 -0600664 (x.replace('_', '-'), power_prefs[x]) for x in power_prefs)
David Burger8ee9b4d2020-06-16 17:40:21 -0600665 _upsert(power_prefs_map, result, 'power')
666 if config_files.camera_map:
667 camera_file = config_files.camera_map.get(config.hw_design.name, {})
668 _upsert(camera_file, result, 'camera')
David Burger52c9d322020-06-09 07:16:18 -0600669 if config_files.dptf_map:
670 # Prefer design specific if found, if not fall back to project wide config
671 # mapped under the empty string.
672 if config_files.dptf_map.get(config.hw_design.name):
673 dptf_file = config_files.dptf_map[config.hw_design.name]
674 else:
675 dptf_file = config_files.dptf_map.get('')
David Burger8ee9b4d2020-06-16 17:40:21 -0600676 _upsert(dptf_file, result, 'thermal')
677 _upsert(config_files.touch_fw, result, 'touch')
Trent Beginf067ccb2020-08-12 12:33:53 -0600678 _upsert(
679 _build_hardware_properties(config.hw_design_config.hardware_topology),
680 result, 'hardware-properties')
David Burger7fd1dbe2020-03-26 09:26:55 -0600681
682 return result
683
684
Andrew Lambcd33f702020-06-11 10:45:16 -0600685def write_output(configs, output=None):
David Burger7fd1dbe2020-03-26 09:26:55 -0600686 """Writes a list of configs to platform JSON format.
687
688 Args:
689 configs: List of config dicts defined in cros_config_schema.yaml
690 output: Target file output (if None, prints to stdout)
691 """
Andrew Lamb2413c982020-05-29 12:15:36 -0600692 json_output = json.dumps({'chromeos': {
693 'configs': configs,
694 }},
695 sort_keys=True,
696 indent=2,
697 separators=(',', ': '))
David Burger7fd1dbe2020-03-26 09:26:55 -0600698 if output:
699 with open(output, 'w') as output_stream:
700 # Using print function adds proper trailing newline.
701 print(json_output, file=output_stream)
702 else:
703 print(json_output)
704
705
Andrew Lambcd33f702020-06-11 10:45:16 -0600706def _feature(name, present):
C Shapiro5bf23a72020-04-24 11:40:17 -0500707 attrib = {'name': name}
708 if present:
709 return etree.Element('feature', attrib=attrib)
Andrew Lambcd33f702020-06-11 10:45:16 -0600710
711 return etree.Element('unavailable-feature', attrib=attrib)
C Shapiro5bf23a72020-04-24 11:40:17 -0500712
713
Andrew Lambcd33f702020-06-11 10:45:16 -0600714def _any_present(features):
Andrew Lamb2413c982020-05-29 12:15:36 -0600715 return topology_pb2.HardwareFeatures.PRESENT in features
C Shapiro5bf23a72020-04-24 11:40:17 -0500716
717
Andrew Lambcd33f702020-06-11 10:45:16 -0600718def _arc_hardware_feature_id(design_config):
C Shapiro5bf23a72020-04-24 11:40:17 -0500719 return design_config.id.value.lower().replace(':', '_')
720
721
Andrew Lambcd33f702020-06-11 10:45:16 -0600722def _write_arc_hardware_feature_file(output_dir, file_name, config_content):
David Burger77a1d312020-05-23 16:05:45 -0600723 output_dir += '/arc'
724 os.makedirs(output_dir, exist_ok=True)
725 output = '%s/%s' % (output_dir, file_name)
Andrew Lamb2413c982020-05-29 12:15:36 -0600726 file_content = minidom.parseString(config_content).toprettyxml(
727 indent=' ', encoding='utf-8')
C Shapiroea33cff2020-05-11 13:32:05 -0500728
729 with open(output, 'wb') as f:
730 f.write(file_content)
731
732
Andrew Lambcd33f702020-06-11 10:45:16 -0600733def _write_arc_hardware_feature_files(config, output_dir, build_root_dir):
C Shapiro5bf23a72020-04-24 11:40:17 -0500734 """Writes ARC hardware_feature.xml files for each config
735
736 Args:
737 config: Source ConfigBundle to process.
738 output_dir: Path to the generated output.
C Shapiro5c877992020-04-29 12:11:28 -0500739 build_root_path: Path to the config file from portage's perspective.
C Shapiro5bf23a72020-04-24 11:40:17 -0500740 Returns:
741 dict that maps the design_config_id onto the correct file.
742 """
Andrew Lambcd33f702020-06-11 10:45:16 -0600743 # pylint: disable=too-many-locals
C Shapiro5bf23a72020-04-24 11:40:17 -0500744 result = {}
C Shapiroea33cff2020-05-11 13:32:05 -0500745 configs_by_design = {}
Sean McAllisterf66887b2020-08-03 14:00:51 -0600746 for hw_design in config.design_list:
C Shapiro5bf23a72020-04-24 11:40:17 -0500747 for design_config in hw_design.configs:
748 hw_features = design_config.hardware_features
Kazuhiro Inaba76d8bb52020-06-26 10:34:07 +0900749 any_camera = hw_features.camera.count.value > 0
Josie Nordrumadc27a72020-07-08 11:05:26 -0600750 multi_camera = hw_features.camera.count.value > 1
Andrew Lambcd33f702020-06-11 10:45:16 -0600751 touchscreen = _any_present([hw_features.screen.touch_support])
C Shapiro5bf23a72020-04-24 11:40:17 -0500752 acc = hw_features.accelerometer
753 gyro = hw_features.gyroscope
754 compass = hw_features.magnetometer
Andrew Lambcd33f702020-06-11 10:45:16 -0600755 light_sensor = hw_features.light_sensor
C Shapiro5bf23a72020-04-24 11:40:17 -0500756 root = etree.Element('permissions')
757 root.extend([
Andrew Lambcd33f702020-06-11 10:45:16 -0600758 _feature('android.hardware.camera', multi_camera),
759 _feature('android.hardware.camera.autofocus', multi_camera),
Kazuhiro Inaba76d8bb52020-06-26 10:34:07 +0900760 _feature('android.hardware.camera.any', any_camera),
761 _feature('android.hardware.camera.front', any_camera),
Andrew Lambcd33f702020-06-11 10:45:16 -0600762 _feature(
763 'android.hardware.sensor.accelerometer',
764 _any_present([acc.lid_accelerometer, acc.base_accelerometer])),
765 _feature('android.hardware.sensor.gyroscope',
766 _any_present([gyro.lid_gyroscope, gyro.base_gyroscope])),
767 _feature(
Andrew Lamb2413c982020-05-29 12:15:36 -0600768 'android.hardware.sensor.compass',
Andrew Lambcd33f702020-06-11 10:45:16 -0600769 _any_present(
770 [compass.lid_magnetometer, compass.base_magnetometer])),
771 _feature(
772 'android.hardware.sensor.light',
773 _any_present(
774 [light_sensor.lid_lightsensor,
775 light_sensor.base_lightsensor])),
776 _feature('android.hardware.touchscreen', touchscreen),
777 _feature('android.hardware.touchscreen.multitouch', touchscreen),
778 _feature('android.hardware.touchscreen.multitouch.distinct',
Andrew Lamb2413c982020-05-29 12:15:36 -0600779 touchscreen),
Andrew Lambcd33f702020-06-11 10:45:16 -0600780 _feature('android.hardware.touchscreen.multitouch.jazzhand',
Andrew Lamb2413c982020-05-29 12:15:36 -0600781 touchscreen),
C Shapiro5bf23a72020-04-24 11:40:17 -0500782 ])
783
C Shapiroea33cff2020-05-11 13:32:05 -0500784 design_name = hw_design.name.lower()
C Shapiro5bf23a72020-04-24 11:40:17 -0500785
C Shapiroea33cff2020-05-11 13:32:05 -0500786 # Constructs the following map:
787 # design_name -> config -> design_configs
788 # This allows any of the following file naming schemes:
789 # - All configs within a design share config (design_name prefix only)
790 # - Nobody shares (full design_name and config id prefix needed)
791 #
792 # Having shared configs when possible makes code reviews easier around
793 # the configs and makes debugging easier on the platform side.
794 config_content = etree.tostring(root)
795 arc_configs = configs_by_design.get(design_name, {})
796 design_configs = arc_configs.get(config_content, [])
797 design_configs.append(design_config)
798 arc_configs[config_content] = design_configs
799 configs_by_design[design_name] = arc_configs
C Shapiro9a3ac8c2020-04-25 07:49:21 -0500800
C Shapiroea33cff2020-05-11 13:32:05 -0500801 for design_name, unique_configs in configs_by_design.items():
802 for file_content, design_configs in unique_configs.items():
Andrew Lamb2413c982020-05-29 12:15:36 -0600803 file_name = 'hardware_features_%s.xml' % design_name
804 if len(unique_configs) == 1:
Andrew Lambcd33f702020-06-11 10:45:16 -0600805 _write_arc_hardware_feature_file(output_dir, file_name, file_content)
C Shapiro9a3ac8c2020-04-25 07:49:21 -0500806
Andrew Lamb2413c982020-05-29 12:15:36 -0600807 for design_config in design_configs:
Andrew Lambcd33f702020-06-11 10:45:16 -0600808 feature_id = _arc_hardware_feature_id(design_config)
Andrew Lamb2413c982020-05-29 12:15:36 -0600809 if len(unique_configs) > 1:
810 file_name = 'hardware_features_%s.xml' % feature_id
Andrew Lambcd33f702020-06-11 10:45:16 -0600811 _write_arc_hardware_feature_file(output_dir, file_name, file_content)
David Burger40dfe3a2020-06-18 17:09:13 -0600812 result[feature_id] = _file_v2('%s/arc/%s' % (build_root_dir, file_name),
813 '/etc/%s' % file_name)
C Shapiro5bf23a72020-04-24 11:40:17 -0500814 return result
815
816
Andrew Lambcd33f702020-06-11 10:45:16 -0600817def _read_config(path):
David Burgerd4f32962020-05-02 12:07:40 -0600818 """Reads a ConfigBundle proto from a json pb file.
David Burgere6f76222020-04-27 11:08:01 -0600819
820 Args:
David Burgerd4f32962020-05-02 12:07:40 -0600821 path: Path to the file encoding the json pb proto.
David Burgere6f76222020-04-27 11:08:01 -0600822 """
823 config = config_bundle_pb2.ConfigBundle()
824 with open(path, 'r') as f:
825 return json_format.Parse(f.read(), config)
826
827
Andrew Lambcd33f702020-06-11 10:45:16 -0600828def _merge_configs(configs):
David Burger7fd1dbe2020-03-26 09:26:55 -0600829 result = config_bundle_pb2.ConfigBundle()
830 for config in configs:
831 result.MergeFrom(config)
832
833 return result
834
835
David Burger1ba78a22020-06-18 18:42:47 -0600836def _camera_map(configs, project_name):
David Burger8ee9b4d2020-06-16 17:40:21 -0600837 """Produces a camera config map for the given configs.
838
839 Produces a map that maps from the design name to the camera config for that
840 design.
841
842 Args:
843 configs: Source ConfigBundle to process.
David Burger1ba78a22020-06-18 18:42:47 -0600844 project_name: Name of project processing for.
David Burger8ee9b4d2020-06-16 17:40:21 -0600845
846 Returns:
847 map from design name to camera config.
848 """
849 result = {}
Sean McAllisterf66887b2020-08-03 14:00:51 -0600850 for design in configs.design_list:
David Burger8ee9b4d2020-06-16 17:40:21 -0600851 design_name = design.name
David Burger0d9e8462020-06-19 14:12:37 -0600852 config_path = CAMERA_CONFIG_SOURCE_PATH_TEMPLATE.format(design_name.lower())
David Burger8ee9b4d2020-06-16 17:40:21 -0600853 if os.path.exists(config_path):
David Burger0d9e8462020-06-19 14:12:37 -0600854 destination = CAMERA_CONFIG_DEST_PATH_TEMPLATE.format(design_name.lower())
David Burger8ee9b4d2020-06-16 17:40:21 -0600855 result[design_name] = {
David Burger1ba78a22020-06-18 18:42:47 -0600856 'config-path':
857 destination,
858 'config-file':
859 _file_v2(os.path.join(project_name, config_path), destination),
David Burger8ee9b4d2020-06-16 17:40:21 -0600860 }
861 return result
862
863
David Burger52c9d322020-06-09 07:16:18 -0600864def _dptf_map(configs, project_name):
865 """Produces a dptf map for the given configs.
866
867 Produces a map that maps from design name to the dptf file config for that
868 design. It looks for the dptf files at:
David Burger2f0d9522020-07-30 10:52:28 -0600869 DPTF_PATH + '/' + DPTF_FILE
David Burger52c9d322020-06-09 07:16:18 -0600870 for a project wide config, that it maps under the empty string, and at:
David Burger2f0d9522020-07-30 10:52:28 -0600871 DPTF_PATH + '/' + design_name + '/' + DPTF_FILE
David Burger52c9d322020-06-09 07:16:18 -0600872 for design specific configs that it maps under the design name.
873
874 Args:
875 configs: Source ConfigBundle to process.
876 project_name: Name of project processing for.
877
878 Returns:
David Burger8ee9b4d2020-06-16 17:40:21 -0600879 map from design name or empty string (project wide), to dptf config.
David Burger52c9d322020-06-09 07:16:18 -0600880 """
881 result = {}
David Burger52c9d322020-06-09 07:16:18 -0600882 # Looking at top level for project wide, and then for each design name
883 # for design specific.
Sean McAllisterf66887b2020-08-03 14:00:51 -0600884 dirs = [""] + [d.name for d in configs.design_list]
David Burger52c9d322020-06-09 07:16:18 -0600885 for directory in dirs:
David Burgera2252762020-07-09 15:09:49 -0600886 design = directory.lower()
887 if os.path.exists(os.path.join(DPTF_PATH, design, DPTF_FILE)):
David Burger2f0d9522020-07-30 10:52:28 -0600888 project_dptf_path = os.path.join(project_name, design, DPTF_FILE)
David Burger52c9d322020-06-09 07:16:18 -0600889 dptf_file = {
890 'dptf-dv':
891 project_dptf_path,
892 'files': [
893 _file(
David Burgera2252762020-07-09 15:09:49 -0600894 os.path.join(project_name, DPTF_PATH, design, DPTF_FILE),
David Burger52c9d322020-06-09 07:16:18 -0600895 os.path.join('/etc/dptf', project_dptf_path))
896 ]
897 }
898 result[directory] = dptf_file
899 return result
900
901
Andrew Lambcd33f702020-06-11 10:45:16 -0600902def Main(project_configs, program_config, output): # pylint: disable=invalid-name
David Burger7fd1dbe2020-03-26 09:26:55 -0600903 """Transforms source proto config into platform JSON.
904
905 Args:
906 project_configs: List of source project configs to transform.
907 program_config: Program config for the given set of projects.
908 output: Output file that will be generated by the transform.
909 """
Andrew Lambcd33f702020-06-11 10:45:16 -0600910 configs = _merge_configs([_read_config(program_config)] +
911 [_read_config(config) for config in project_configs])
C Shapiro5bf23a72020-04-24 11:40:17 -0500912 arc_hw_feature_files = {}
C Shapiro2b6d5332020-05-06 17:51:35 -0500913 touch_fw = {}
David Burger52c9d322020-06-09 07:16:18 -0600914 dptf_map = {}
David Burger8ee9b4d2020-06-16 17:40:21 -0600915 camera_map = {}
C Shapiro5bf23a72020-04-24 11:40:17 -0500916 output_dir = os.path.dirname(output)
C Shapiro5c877992020-04-29 12:11:28 -0500917 build_root_dir = output_dir
C Shapiro5c877992020-04-29 12:11:28 -0500918 if 'sw_build_config' in output_dir:
919 full_path = os.path.realpath(output)
Andrew Lamb2413c982020-05-29 12:15:36 -0600920 project_name = re.match(r'.*/(\w*)/sw_build_config/.*',
921 full_path).groups(1)[0]
C Shapiro5c877992020-04-29 12:11:28 -0500922 # Projects don't know about each other until they are integrated into the
923 # build system. When this happens, the files need to be able to co-exist
924 # without any collisions. This prefixes the project name (which is how
925 # portage maps in the project), so project files co-exist and can be
926 # installed together.
927 # This is necessary to allow projects to share files at the program level
928 # without having portage file installation collisions.
929 build_root_dir = os.path.join(project_name, output_dir)
C Shapiro6830e6c2020-04-29 13:29:56 -0500930
David Burger1ba78a22020-06-18 18:42:47 -0600931 camera_map = _camera_map(configs, project_name)
David Burger52c9d322020-06-09 07:16:18 -0600932 dptf_map = _dptf_map(configs, project_name)
933
C Shapiro2b6d5332020-05-06 17:51:35 -0500934 if os.path.exists(TOUCH_PATH):
Andrew Lambcd33f702020-06-11 10:45:16 -0600935 touch_fw = _build_touch_file_config(configs, project_name)
Andrew Lambcd33f702020-06-11 10:45:16 -0600936 arc_hw_feature_files = _write_arc_hardware_feature_files(
937 configs, output_dir, build_root_dir)
C Shapiro5bf23a72020-04-24 11:40:17 -0500938 config_files = ConfigFiles(
C Shapiro5bf23a72020-04-24 11:40:17 -0500939 arc_hw_features=arc_hw_feature_files,
C Shapiro2b6d5332020-05-06 17:51:35 -0500940 touch_fw=touch_fw,
David Burger8ee9b4d2020-06-16 17:40:21 -0600941 dptf_map=dptf_map,
David Burgerdd3c1272020-08-24 12:45:03 -0600942 camera_map=camera_map)
Andrew Lambcd33f702020-06-11 10:45:16 -0600943 write_output(_transform_build_configs(configs, config_files), output)
David Burger7fd1dbe2020-03-26 09:26:55 -0600944
945
946def main(argv=None):
947 """Main program which parses args and runs
948
949 Args:
950 argv: List of command line arguments, if None uses sys.argv.
951 """
952 if argv is None:
953 argv = sys.argv[1:]
Andrew Lambcd33f702020-06-11 10:45:16 -0600954 opts = parse_args(argv)
David Burger7fd1dbe2020-03-26 09:26:55 -0600955 Main(opts.project_configs, opts.program_config, opts.output)
956
957
958if __name__ == '__main__':
959 sys.exit(main(sys.argv[1:]))