1"""Functions related to hardware features. 2 3See proto definitions for descriptions of arguments. 4""" 5 6# Needed to load from @proto. Add @unused to silence lint. 7load("//config/util/bindings/proto.star", "protos") 8load( 9 "@proto//chromiumos/config/api/component.proto", 10 comp_pb = "chromiumos.config.api", 11) 12load( 13 "@proto//chromiumos/config/api/topology.proto", 14 topo_pb = "chromiumos.config.api", 15) 16 17_HW_FEAT = topo_pb.HardwareFeatures 18 19_PRESENT = struct( 20 UNKNOWN = topo_pb.HardwareFeatures.PRESENT_UNKNOWN, 21 PRESENT = topo_pb.HardwareFeatures.PRESENT, 22 NOT_PRESENT = topo_pb.HardwareFeatures.NOT_PRESENT, 23) 24 25def _bool_to_present(value): 26 """Returns correct value of present enum depending on value""" 27 if value == None: 28 return _PRESENT.UNKNOWN 29 elif value: 30 return _PRESENT.PRESENT 31 else: 32 return _PRESENT.NOT_PRESENT 33 34def _create_bluetooth(present = True): 35 """Specify whether bluetooth is present""" 36 return _HW_FEAT( 37 bluetooth = _HW_FEAT.Bluetooth( 38 present = _bool_to_present(present), 39 ), 40 ) 41 42def _create_hotwording(supported = True): 43 """Specify whether hotwording is supported""" 44 return _HW_FEAT( 45 hotwording = _HW_FEAT.Hotwording( 46 present = _bool_to_present(supported), 47 ), 48 ) 49 50def _create_display(internal, external): 51 """Specify type of display support present.""" 52 types = { 53 (False, False): _HW_FEAT.Display.TYPE_UNKNOWN, 54 (True, False): _HW_FEAT.Display.TYPE_INTERNAL, 55 (False, True): _HW_FEAT.Display.TYPE_EXTERNAL, 56 (True, True): _HW_FEAT.Display.TYPE_INTERNAL_EXTERNAL, 57 } 58 59 return _HW_FEAT( 60 display = _HW_FEAT.Display( 61 type = types[(internal, external)], 62 ), 63 ) 64 65_FORM_FACTOR = struct( 66 CLAMSHELL = _HW_FEAT.FormFactor.CLAMSHELL, 67 CONVERTIBLE = _HW_FEAT.FormFactor.CONVERTIBLE, 68 DETACHABLE = _HW_FEAT.FormFactor.DETACHABLE, 69 CHROMEBASE = _HW_FEAT.FormFactor.CHROMEBASE, 70 CHROMEBOX = _HW_FEAT.FormFactor.CHROMEBOX, 71 CHROMEBIT = _HW_FEAT.FormFactor.CHROMEBIT, 72 CHROMESLATE = _HW_FEAT.FormFactor.CHROMESLATE, 73) 74 75_RECOVERY_INPUT = struct( 76 KEYBOARD = _HW_FEAT.FormFactor.KEYBOARD, 77 POWER_BUTTON = _HW_FEAT.FormFactor.POWER_BUTTON, 78 RECOVERY_BUTTON = _HW_FEAT.FormFactor.RECOVERY_BUTTON, 79) 80 81_EC = struct( 82 CHROME = _HW_FEAT.EmbeddedController.EC_CHROME, 83 WILCO = _HW_FEAT.EmbeddedController.EC_WILCO, 84) 85 86def _create_ec(ec_type, present = True): 87 """Specify the embedded controller type.""" 88 return _HW_FEAT( 89 embedded_controller = _HW_FEAT.EmbeddedController( 90 present = _bool_to_present(present), 91 ec_type = ec_type, 92 ), 93 ) 94 95_LOCATION = struct( 96 UNKNOWN = _HW_FEAT.Fingerprint.LOCATION_UNKNOWN, 97 SCREEN_TOP_LEFT = _HW_FEAT.Fingerprint.POWER_BUTTON_TOP_LEFT, 98 KEYBOARD_BOTTOM_LEFT = _HW_FEAT.Fingerprint.KEYBOARD_BOTTOM_LEFT, 99 KEYBOARD_BOTTOM_RIGHT = _HW_FEAT.Fingerprint.KEYBOARD_BOTTOM_RIGHT, 100 KEYBOARD_TOP_RIGHT = _HW_FEAT.Fingerprint.KEYBOARD_TOP_RIGHT, 101 SIDE_RIGHT = _HW_FEAT.Fingerprint.RIGHT_SIDE, 102 SIDE_LEFT = _HW_FEAT.Fingerprint.LEFT_SIDE, 103 LEFT_OF_POWER_BUTTON_TOP_RIGHT = _HW_FEAT.Fingerprint.LEFT_OF_POWER_BUTTON_TOP_RIGHT, 104) 105 106def _create_fingerprint( 107 present = False, 108 location = _LOCATION.UNKNOWN, 109 board = "", 110 ro_version = "", 111 fingerprint_diag = None): 112 """Specify fingerprint settings""" 113 return _HW_FEAT( 114 fingerprint = _HW_FEAT.Fingerprint( 115 location = location, 116 board = board, 117 ro_version = ro_version, 118 fingerprint_diag = fingerprint_diag, 119 present = present, 120 ), 121 ) 122 123def _create_form_factor(form_factor, recovery_input = None): 124 """Specify the form factor as a HardwareFeature.""" 125 return _HW_FEAT( 126 form_factor = _HW_FEAT.FormFactor( 127 form_factor = form_factor, 128 recovery_input = recovery_input, 129 ), 130 ) 131 132_KB_TYPE = struct( 133 NONE = _HW_FEAT.Keyboard.NONE, 134 INTERNAL = _HW_FEAT.Keyboard.INTERNAL, 135 DETACHABLE = _HW_FEAT.Keyboard.DETACHABLE, 136) 137 138def _create_keyboard( 139 kb_type, 140 backlight = False, 141 pwr_btn_present = False, 142 numpad_present = False): 143 """Builds a Topology proto for a keyboard. 144 145 Args: 146 kb_type: A KeyboardType enum. Required. 147 backlight: True if a backlight is present. Required. 148 pwr_btn_present: True if a power button is present. Required. 149 numpad_present: True if numeric pad is present. 150 """ 151 return _HW_FEAT( 152 keyboard = _HW_FEAT.Keyboard( 153 keyboard_type = kb_type, 154 backlight = _bool_to_present(backlight), 155 power_button = _bool_to_present(pwr_btn_present), 156 numeric_pad = _bool_to_present(numpad_present), 157 ), 158 ) 159 160_STORAGE = struct( 161 EMMC = comp_pb.Component.Storage.EMMC, 162 NVME = comp_pb.Component.Storage.NVME, 163 SATA = comp_pb.Component.Storage.SATA, 164 UFS = comp_pb.Component.Storage.UFS, 165 BRIDGED_EMMC = comp_pb.Component.Storage.BRIDGED_EMMC, 166) 167 168def _create_storage(type): 169 """Specify storage type.""" 170 return _HW_FEAT( 171 storage = _HW_FEAT.Storage( 172 storage_type = type, 173 ), 174 ) 175 176def _create_screen( 177 touch = False, 178 inches = 0, 179 width_px = None, 180 height_px = None, 181 pixels_per_in = None, 182 privacy_screen = False): 183 """Specify features of screen""" 184 185 return _HW_FEAT( 186 screen = _HW_FEAT.Screen( 187 touch_support = _bool_to_present(touch), 188 panel_properties = comp_pb.Component.DisplayPanel.Properties( 189 diagonal_milliinch = inches * 1000, 190 width_px = width_px, 191 height_px = height_px, 192 pixels_per_in = pixels_per_in, 193 ), 194 ), 195 privacy_screen = _HW_FEAT.PrivacyScreen( 196 present = _bool_to_present(privacy_screen), 197 ), 198 ) 199 200def _create_touchpad(present = True): 201 """Specify whether touchpad is present.""" 202 return _HW_FEAT( 203 touchpad = _HW_FEAT.Touchpad( 204 present = _bool_to_present(present), 205 ), 206 ) 207 208def _create_microphone_mute_switch(present = False): 209 """Specify whether audio input mute switch is present.""" 210 return _HW_FEAT( 211 microphone_mute_switch = _HW_FEAT.MicrophoneMuteSwitch( 212 present = _bool_to_present(present), 213 ), 214 ) 215 216def _create_battery(no_battery_boot_supported = False): 217 """Specify whether no battery boot is supported.""" 218 return _HW_FEAT( 219 battery = _HW_FEAT.Battery( 220 no_battery_boot_supported = no_battery_boot_supported, 221 ), 222 ) 223 224# build struct of enums to configure camera 225_camera_features = struct( 226 facing = struct( 227 UNKNOWN = _HW_FEAT.Camera.FACING_UNKNOWN, 228 FRONT = _HW_FEAT.Camera.FACING_FRONT, 229 BACK = _HW_FEAT.Camera.FACING_BACK, 230 ), 231 interface = struct( 232 UNKNOWN = _HW_FEAT.Camera.INTERFACE_UNKNOWN, 233 USB = _HW_FEAT.Camera.INTERFACE_USB, 234 MIPI = _HW_FEAT.Camera.INTERFACE_MIPI, 235 ), 236 orientation = struct( 237 UNKNOWN = _HW_FEAT.Camera.ORIENTATION_UNKNOWN, 238 _0_DEG = _HW_FEAT.Camera.ORIENTATION_0, 239 _90_DEG = _HW_FEAT.Camera.ORIENTATION_90, 240 _180_DEG = _HW_FEAT.Camera.ORIENTATION_180, 241 _270_DEG = _HW_FEAT.Camera.ORIENTATION_270, 242 ), 243) 244 245def _create_camera( 246 facing = _camera_features.facing.UNKNOWN, 247 flags = 0, 248 ids = [], 249 interface = _camera_features.interface.UNKNOWN, 250 orientation = _camera_features.orientation.UNKNOWN, 251 privacy_switch = None): 252 """Take camera features and create a Camera.Device instance. 253 254 Pass one or more of these instances to create_cameras() to build 255 a full HardwareFeature proto from them. 256 """ 257 return _HW_FEAT.Camera.Device( 258 facing = facing, 259 flags = flags, 260 ids = ids, 261 interface = interface, 262 orientation = orientation, 263 privacy_switch = _bool_to_present(privacy_switch), 264 ) 265 266def _create_cameras(*args): 267 """Take one or more cameras and create HardwareFeature from them.""" 268 return _HW_FEAT( 269 camera = _HW_FEAT.Camera( 270 devices = args, 271 ), 272 ) 273 274_STYLUS_TYPE = struct( 275 NONE = _HW_FEAT.Stylus.NONE, 276 INTERNAL = _HW_FEAT.Stylus.INTERNAL, 277 EXTERNAL = _HW_FEAT.Stylus.EXTERNAL, 278) 279 280def _create_stylus(stylus_type): 281 """Create stylus feature.""" 282 return _HW_FEAT( 283 stylus = _HW_FEAT.Stylus( 284 stylus = stylus_type, 285 ), 286 ) 287 288def _create_features( 289 battery = None, 290 bluetooth = None, 291 camera = None, 292 display = None, 293 ec = _create_ec(_EC.CHROME), # non-chrome ECs are very rare 294 fingerprint = None, 295 form_factor = None, 296 hotwording = None, 297 keyboard = None, 298 proximity = None, 299 screen = None, 300 storage = None, 301 stylus = None, 302 touchpad = None, 303 microphone_mute_switch = None): 304 hw_feat = {} 305 306 def _merge(name, feature): 307 if feature: 308 hw_feat[name] = getattr(feature, name) 309 310 _merge("battery", battery) 311 _merge("bluetooth", bluetooth) 312 _merge("camera", camera) 313 _merge("display", display) 314 _merge("embedded_controller", ec) 315 _merge("fingerprint", fingerprint) 316 _merge("form_factor", form_factor) 317 _merge("hotwording", hotwording) 318 _merge("keyboard", keyboard) 319 _merge("proximity", proximity) 320 _merge("screen", screen) 321 _merge("storage", storage) 322 _merge("stylus", stylus) 323 _merge("touchpad", touchpad) 324 _merge("microphone_mute_switch", microphone_mute_switch) 325 326 return _HW_FEAT(**hw_feat) 327 328hw_feat = struct( 329 create_battery = _create_battery, 330 create_bluetooth = _create_bluetooth, 331 create_camera = _create_camera, 332 create_cameras = _create_cameras, 333 create_display = _create_display, 334 create_ec = _create_ec, 335 create_fingerprint = _create_fingerprint, 336 create_features = _create_features, 337 create_form_factor = _create_form_factor, 338 create_hotwording = _create_hotwording, 339 create_keyboard = _create_keyboard, 340 create_screen = _create_screen, 341 create_storage = _create_storage, 342 create_stylus = _create_stylus, 343 create_touchpad = _create_touchpad, 344 create_microphone_mute_switch = _create_microphone_mute_switch, 345 346 # export enums 347 camera_features = _camera_features, 348 embedded_controller = _EC, 349 form_factor = _FORM_FACTOR, 350 recovery_input = _RECOVERY_INPUT, 351 keyboard_type = _KB_TYPE, 352 present = _PRESENT, 353 storage = _STORAGE, 354 stylus_type = _STYLUS_TYPE, 355 location = _LOCATION, 356) 357