Skip to content

Commit a62c5bf

Browse files
committed
VSS based OEM VHAL
- Change VSS permission naming scheme. - Rename VSS VHAL to more generic OEM VHAL. - Simplify parameters. Signed-off-by: Jan Kubovy <jan.kubovy@bmw.de>
1 parent 2479a79 commit a62c5bf

17 files changed

+3629
-963
lines changed

src/vss_tools/exporters/vhal.py

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#
77
# SPDX-License-Identifier: MPL-2.0
88

9+
import os
910
from pathlib import Path
1011

1112
import rich_click as click
@@ -33,17 +34,11 @@
3334
required=False,
3435
help="Read a json file list of VSS paths which should be considered as continuous change mode.",
3536
)
36-
@click.option(
37-
"--output-dir",
38-
type=click.Path(dir_okay=True, readable=True, path_type=Path, exists=True),
39-
required=True,
40-
help="Output directory, where vhal specific generated files are saved into.",
41-
)
4237
@click.option(
4338
"--property-group",
4439
type=int,
4540
required=False,
46-
default=1,
41+
default=4,
4742
show_default=True,
4843
help="""
4944
Group of generated VHAL properties: 1 = SYSTEM, 2 = VENDOR, 3 = BACKPORTED, 4 = VSS.
@@ -79,13 +74,37 @@
7974
default=False,
8075
show_default=True,
8176
)
77+
@click.option(
78+
"--property-version",
79+
type=int,
80+
required=False,
81+
default=4,
82+
show_default=True,
83+
help="""
84+
The vehicle property's AIDL interface version used in
85+
https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
86+
Currently, all properties use the same version.
87+
""",
88+
)
89+
@click.option(
90+
"--aosp-workspace-path",
91+
type=click.Path(dir_okay=True, readable=True, path_type=Path, exists=True),
92+
required=True,
93+
help="""
94+
Path to AOSP workspace. If provided, XML files for the car service will be generated by
95+
extending the existing XML files with permission declarations and resource strings for VSS.
96+
If not provided, the generated xml files will only include the permissions and resource
97+
strings required for VSS.
98+
""",
99+
)
82100
def cli(
83101
vspec: Path,
84102
vhal_map: Path,
85103
continuous_change_mode: Path | None,
86-
output_dir: Path,
87104
extend_new: bool,
88105
property_group: int,
106+
property_version: int,
107+
aosp_workspace_path: Path,
89108
min_property_id: int,
90109
override_vhal_units: bool,
91110
override_vhal_datatype: bool,
@@ -119,10 +138,18 @@ def cli(
119138
mapper.load_continuous_list(continuous_change_mode)
120139
mapper.load(vhal_map, tree)
121140
mapper.safe(vhal_map)
141+
log.info(f"Updated: {vhal_map}")
122142

123-
java_output = output_dir / "VehiclePropertyIdsVss.java"
124-
permissions_output = output_dir / "VssPermissions.java"
143+
java_output_dir = aosp_workspace_path / "vendor/car/packages/services/Car/car-lib/src/android/car/oem"
144+
os.makedirs(java_output_dir, exist_ok=True)
145+
java_output = java_output_dir / "VehiclePropertyIdsOem.java"
146+
permissions_output = java_output_dir / "OemPermissions.java"
125147
mapper.generate_java_files(java_output, permissions_output)
148+
log.info(f"Written: {java_output}")
149+
log.info(f"Written: {permissions_output}")
150+
151+
aidl_output = aosp_workspace_path / "vendor/car/hardware/interfaces/automotive/vehicle/aidl_property/vendor/android/hardware/automotive/vehicle/VehiclePropertyOem.aidl"
152+
mapper.generate_aidl_file(aidl_output, property_version)
153+
log.info(f"Written: {aidl_output}")
126154

127-
aidl_output = output_dir / "VehiclePropertyVss.aidl"
128-
mapper.generate_aidl_file(aidl_output)
155+
mapper.generate_xml_files(aosp_workspace_path)

src/vss_tools/utils/vhal/property_constants.py

Lines changed: 106 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ def __str__(self) -> str:
3333
}
3434
return d.get(self, f"VehicleAreaType.{self.name}")
3535

36+
@staticmethod
37+
def get_java_doc(area: int) -> str:
38+
if area == 0:
39+
return "VEHICLE_AREA_TYPE_GLOBAL"
40+
elif area == 7:
41+
return "VEHICLE_AREA_TYPE_VENDOR"
42+
else:
43+
logging.error(f"Vehicle property access must be 0 or 7, was {area}")
44+
sys.exit(1)
45+
3646

3747
class VhalPropertyGroup(Enum):
3848
"""
@@ -43,7 +53,7 @@ class VhalPropertyGroup(Enum):
4353
VEHICLE_PROPERTY_GROUP_SYSTEM = int(0x10000000) # VehiclePropertyGroup.SYSTEM aidl
4454
VEHICLE_PROPERTY_GROUP_VENDOR = int(0x20000000) # VehiclePropertyGroup.VENDOR aidl
4555
VEHICLE_PROPERTY_GROUP_BACKPORTED = int(0x30000000) # VehiclePropertyGroup.BACKPORTED aidl
46-
VEHICLE_PROPERTY_GROUP_VSS = int(0x40000000) # VehiclePropertyGroup.VSS aidl (COVESA)
56+
VEHICLE_PROPERTY_GROUP_OEM = int(0x40000000) # VehiclePropertyGroup.OEM aidl (COVESA)
4757

4858
@staticmethod
4959
def get(group: int):
@@ -54,21 +64,49 @@ def get(group: int):
5464
elif group == 3:
5565
return VhalPropertyGroup.VEHICLE_PROPERTY_GROUP_BACKPORTED
5666
elif group == 4:
57-
return VhalPropertyGroup.VEHICLE_PROPERTY_GROUP_VSS
67+
return VhalPropertyGroup.VEHICLE_PROPERTY_GROUP_OEM
5868
else:
5969
logging.error(f"Group must be between 1 and 4, was {group}")
6070
sys.exit(1)
6171

62-
def __str__(self):
72+
def __str__(self) -> str:
6373
d = {
64-
self.VEHICLE_PROPERTY_GROUP_SYSTEM: "VehiclePropertyGroup.SYSTEM",
65-
self.VEHICLE_PROPERTY_GROUP_VENDOR: "VehiclePropertyGroup.VENDOR",
66-
self.VEHICLE_PROPERTY_GROUP_BACKPORTED: "VehiclePropertyGroup.BACKPORTED",
67-
self.VEHICLE_PROPERTY_GROUP_VSS: "VehiclePropertyGroup.VSS",
74+
VhalPropertyGroup.VEHICLE_PROPERTY_GROUP_SYSTEM: "VehiclePropertyGroup.SYSTEM",
75+
VhalPropertyGroup.VEHICLE_PROPERTY_GROUP_VENDOR: "VehiclePropertyGroup.VENDOR",
76+
VhalPropertyGroup.VEHICLE_PROPERTY_GROUP_BACKPORTED: "VehiclePropertyGroup.BACKPORTED",
77+
VhalPropertyGroup.VEHICLE_PROPERTY_GROUP_OEM: "VehiclePropertyGroup.OEM",
6878
}
6979
return d.get(self, "VehiclePropertyGroup.SYSTEM")
7080

7181

82+
class VhalPropertyType(Enum):
83+
VEHICLE_PROPERTY_TYPE_STRING = int(0x00100000) # VehiclePropertyType.STRING
84+
VEHICLE_PROPERTY_TYPE_BOOLEAN = int(0x00200000) # VehiclePropertyType.BOOLEAN
85+
VEHICLE_PROPERTY_TYPE_INT32 = int(0x00400000) # VehiclePropertyType.INT32
86+
VEHICLE_PROPERTY_TYPE_INT32_VEC = int(0x00410000) # VehiclePropertyType.INT32_VEC
87+
VEHICLE_PROPERTY_TYPE_INT64 = int(0x00500000) # VehiclePropertyType.INT64
88+
VEHICLE_PROPERTY_TYPE_INT64_VEC = int(0x00510000) # VehiclePropertyType.INT64_VEC
89+
VEHICLE_PROPERTY_TYPE_FLOAT = int(0x00600000) # VehiclePropertyType.FLOAT
90+
VEHICLE_PROPERTY_TYPE_FLOAT_VEC = int(0x00610000) # VehiclePropertyType.FLOAT_VEC
91+
VEHICLE_PROPERTY_TYPE_BYTES = int(0x00700000) # VehiclePropertyType.BYTES
92+
VEHICLE_PROPERTY_TYPE_MIXED = int(0x00E00000) # VehiclePropertyType.MIXED
93+
94+
def __str__(self) -> str:
95+
d = {
96+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_STRING: "VehiclePropertyType.STRING",
97+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_BOOLEAN: "VehiclePropertyType.BOOLEAN",
98+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_INT32: "VehiclePropertyType.INT32",
99+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_INT32_VEC: "VehiclePropertyType.INT32_VEC",
100+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_INT64: "VehiclePropertyType.INT64",
101+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_INT64_VEC: "VehiclePropertyType.INT64_VEC",
102+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_FLOAT: "VehiclePropertyType.FLOAT",
103+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_FLOAT_VEC: "VehiclePropertyType.FLOAT_VEC",
104+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_BYTES: "VehiclePropertyType.BYTES",
105+
VhalPropertyType.VEHICLE_PROPERTY_TYPE_MIXED: "VehiclePropertyType.MIXED",
106+
}
107+
return d.get(self, "Unsupported")
108+
109+
72110
class VSSDatatypesToVhal:
73111
"""
74112
Mapping of vss datatypes corresponding to standard VHAL property type IDs. For those VSS datatypes, which don't
@@ -87,27 +125,26 @@ class VSSDatatypesToVhal:
87125
Datatypes.INT64_ARRAY[0]: int(0x00510000), # INT64_VEC
88126
Datatypes.FLOAT[0]: int(0x00600000), # FLOAT
89127
Datatypes.FLOAT_ARRAY[0]: int(0x00610000), # FLOAT_VEC
90-
# Further VSS types mapped to vendor hex values
91-
Datatypes.STRING_ARRAY[0]: int(0x00110000),
92-
Datatypes.BOOLEAN_ARRAY[0]: int(0x00210000),
93-
Datatypes.INT8[0]: int(0x00300000),
94-
Datatypes.INT8_ARRAY[0]: int(0x00310000),
95-
Datatypes.UINT8[0]: int(0x00320000),
96-
Datatypes.UINT8_ARRAY[0]: int(0x00330000),
97-
Datatypes.INT16[0]: int(0x00340000),
98-
Datatypes.INT16_ARRAY[0]: int(0x00350000),
99-
Datatypes.UINT16[0]: int(0x00360000),
100-
Datatypes.UINT16_ARRAY[0]: int(0x00370000),
101-
Datatypes.UINT32[0]: int(0x00420000),
102-
Datatypes.UINT32_ARRAY[0]: int(0x00430000),
103-
Datatypes.UINT64[0]: int(0x00520000),
104-
Datatypes.UINT64_ARRAY[0]: int(0x00530000),
105-
Datatypes.DOUBLE[0]: int(0x00800000),
106-
Datatypes.DOUBLE_ARRAY[0]: int(0x00810000),
107-
Datatypes.NUMERIC[0]: int(0x00820000),
108-
Datatypes.NUMERIC_ARRAY[0]: int(0x00830000),
128+
# Further VSS types mapped to hex values of supported types
129+
Datatypes.STRING_ARRAY[0]: int(0x00100000), # STRING
130+
Datatypes.BOOLEAN_ARRAY[0]: int(0x00410000), # INT32_VEC
131+
Datatypes.INT8[0]: int(0x00400000), # INT32
132+
Datatypes.INT8_ARRAY[0]: int(0x00410000), # INT32_VEC
133+
Datatypes.UINT8[0]: int(0x00400000), # INT32
134+
Datatypes.UINT8_ARRAY[0]: int(0x00410000), # INT32_VEC
135+
Datatypes.INT16[0]: int(0x00400000), # INT32
136+
Datatypes.INT16_ARRAY[0]: int(0x00410000), # INT32_VEC
137+
Datatypes.UINT16[0]: int(0x00400000), # INT32
138+
Datatypes.UINT16_ARRAY[0]: int(0x00410000), # INT32_VEC
139+
Datatypes.UINT32[0]: int(0x00400000), # INT32
140+
Datatypes.UINT32_ARRAY[0]: int(0x00410000), # INT32_VEC
141+
Datatypes.UINT64[0]: int(0x00500000), # INT64
142+
Datatypes.UINT64_ARRAY[0]: int(0x00510000), # INT64_VEC
143+
Datatypes.DOUBLE[0]: int(0x00600000), # fallback to FLOAT
144+
Datatypes.DOUBLE_ARRAY[0]: int(0x00610000), # fallback to FLOAT_VEC
145+
Datatypes.NUMERIC[0]: int(0x00600000), # fallback to FLOAT
146+
Datatypes.NUMERIC_ARRAY[0]: int(0x00610000), # fallback to FLOAT_VEC
109147
}
110-
VHAL_TO_VSS_TYPE_MAP = {v: k for k, v in VSS_TO_VHAL_TYPE_MAP.items()}
111148

112149
@classmethod
113150
def get_property_type_id(cls, vss_datatype: str) -> int:
@@ -130,11 +167,11 @@ def get_property_type_repr(cls, datatype_id: int) -> str:
130167
@param datatype_id: datatype Integer representation.
131168
@return: String representation of a datatype
132169
"""
133-
datatype_name = VSSDatatypesToVhal.VHAL_TO_VSS_TYPE_MAP.get(datatype_id)
170+
datatype_name = str(VhalPropertyType(datatype_id))
134171
if not datatype_name:
135172
raise Exception(f"Invalid property type id {datatype_id}, must be one of IDs listed in VSSDataTypeToVhal")
136173

137-
return f"VehiclePropertyType.{datatype_name}"
174+
return datatype_name
138175

139176

140177
class VehiclePropertyAccess(IntEnum):
@@ -147,6 +184,26 @@ class VehiclePropertyAccess(IntEnum):
147184
WRITE = 2
148185
READ_WRITE = 3
149186

187+
def __str__(self):
188+
d = {
189+
VehiclePropertyAccess.READ: "VehiclePropertyAccess.READ",
190+
VehiclePropertyAccess.WRITE: "VehiclePropertyAccess.WRITE",
191+
VehiclePropertyAccess.READ_WRITE: "VehiclePropertyAccess.READ_WRITE",
192+
}
193+
return d.get(self, "VehiclePropertyAccess.READ")
194+
195+
@staticmethod
196+
def get_java_doc(access: int) -> str:
197+
if access == 1:
198+
return "VEHICLE_PROPERTY_ACCESS_READ"
199+
elif access == 2:
200+
return "VEHICLE_PROPERTY_ACCESS_WRITE"
201+
elif access == 3:
202+
return "VEHICLE_PROPERTY_ACCESS_READ_WRITE"
203+
else:
204+
logging.error(f"Vehicle property access must be between 1 and 3, was {access}")
205+
sys.exit(1)
206+
150207

151208
class VehiclePropertyChangeMode(Enum):
152209
"""
@@ -157,3 +214,23 @@ class VehiclePropertyChangeMode(Enum):
157214
STATIC = 0
158215
ON_CHANGE = 1
159216
CONTINUOUS = 2
217+
218+
def __str__(self) -> str:
219+
d = {
220+
VehiclePropertyChangeMode.STATIC: "VehiclePropertyChangeMode.STATIC",
221+
VehiclePropertyChangeMode.ON_CHANGE: "VehiclePropertyChangeMode.ON_CHANGE",
222+
VehiclePropertyChangeMode.CONTINUOUS: "VehiclePropertyChangeMode.CONTINUOUS",
223+
}
224+
return d.get(self, "VehiclePropertyChangeMode.STATIC")
225+
226+
@staticmethod
227+
def get_java_doc(mode: int) -> str:
228+
if mode == 0:
229+
return "VEHICLE_PROPERTY_CHANGE_MODE_STATIC"
230+
elif mode == 1:
231+
return "VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE"
232+
elif mode == 2:
233+
return "VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS"
234+
else:
235+
logging.error(f"Change mode must be between 0 and 2, was {mode}")
236+
sys.exit(1)

0 commit comments

Comments
 (0)