Repository navigation
HAL Version Use Cases
Every version of an interface is released the same way: the version is tagged, and a new
<component>/<version>/ directory is created for it. That released directory never changes.
This is what "frozen" means, and it is the same before and after stable AIDL. What changes at
stable AIDL is the compatibility rule, not how a version is released:
| Era | Version | Compatibility rule |
|---|---|---|
Pre-release (era 0, today) |
0.<major>.<minor>.<bugfix> |
A breaking change is allowed and bumps the major. Compatible within one major only |
Stable AIDL (era 1+) |
Single integer counting up: V1, V2, V3 … |
Additive only. Every version stays backwards compatible, so every pairing is compatible |
In era 0 the vendor must be on the same major as the MW, at or above its minor
(Versioning Guide).
Cases 1–16 are era 0.
Requirement IDs refer to Requirements at the end of this page.
Blue = MW. Amber = vendor. Solid arrow = works. Dotted arrow = does not.
OK.
Requirements: VER-1, CON-1, CON-2, BLD-3
flowchart LR
MW["MW<br/>videodecoder 0.2.1.0"]:::mw -- "ok" --> V["Vendor<br/>videodecoder 0.2.1.0"]:::ven
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
OK.
Requirements: VER-1, VER-2, CON-2
flowchart LR
MW["MW<br/>videodecoder 0.2.1.0"]:::mw -- "ok — vendor ahead" --> V["Vendor<br/>videodecoder 0.2.3.0"]:::ven
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
OK.
Requirements: VER-1, VER-2, VER-4, CON-2
flowchart LR
MW["MW<br/>videodecoder 0.2.1.0"]:::mw -- "ok — interface unchanged" --> V["Vendor<br/>videodecoder 0.2.1.1"]:::ven
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
OK. The vendor is at or above every consumer.
Requirements: VER-2, CON-1, BLD-4
flowchart LR
subgraph MW["MW"]
P["player<br/>0.2.0.0"]:::mw
R["recorder<br/>0.2.1.0"]:::mw
D["diagnostics<br/>0.2.3.0"]:::mw
end
P -- "ok" --> V["Vendor<br/>videodecoder 0.2.3.0"]:::ven
R -- "ok" --> V
D -- "ok" --> V
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
style MW fill:#f8fafc,stroke:#94a3b8,color:#000
OK. Alignment is per component, not per layer.
Requirements: VER-3, CON-2, CON-4, BLD-4
flowchart LR
subgraph MW["MW pins"]
M1["videodecoder 0.2.1.0"]:::mw
M2["audiodecoder 0.3.0.0"]:::mw
M3["hdmicec 0.2.0.0"]:::mw
M4["panel 0.4.1.0"]:::mw
end
subgraph VV["Vendor vertical"]
subgraph SOC["SoC layer"]
S1["videodecoder 0.2.2.0"]:::ven
S2["audiodecoder 0.3.0.0"]:::ven
end
subgraph OEM["OEM layer"]
O1["hdmicec 0.2.0.1"]:::ven
O2["panel 0.4.1.0"]:::ven
end
end
M1 -- "ok" --> S1
M2 -- "ok" --> S2
M3 -- "ok" --> O1
M4 -- "ok" --> O2
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
style MW fill:#f8fafc,stroke:#94a3b8,color:#000
style VV fill:#f8fafc,stroke:#94a3b8,color:#000
style SOC fill:#f8fafc,stroke:#94a3b8,color:#000
style OEM fill:#f8fafc,stroke:#94a3b8,color:#000
OK. The MW pins the lowest minor that every platform delivers.
Requirements: VER-3, CON-3, BLD-6
flowchart LR
MW["Common MW<br/>videodecoder 0.2.1.0"]:::mw
MW -- "ok" --> A["Platform A vertical<br/>videodecoder 0.2.3.0"]:::ven
MW -- "ok" --> B["Platform B vertical<br/>videodecoder 0.2.1.0"]:::ven
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
Not supported. The MW may call methods the vendor does not implement. isCompatible() rejects it.
flowchart LR
MW["MW<br/>videodecoder 0.2.3.0"]:::mw -. "rejected — vendor behind" .-> V["Vendor<br/>videodecoder 0.2.1.0"]:::bad
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef bad fill:#fee2e2,stroke:#b91c1c,color:#000
Not supported.
Requirements: VER-3, VER-6, CON-7
flowchart LR
MW["MW<br/>videodecoder 0.3.0.0"]:::mw -. "rejected — major not aligned" .-> V["Vendor<br/>videodecoder 0.2.3.0"]:::bad
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef bad fill:#fee2e2,stroke:#b91c1c,color:#000
Not supported.
Requirements: VER-3, VER-6, CON-7
flowchart LR
MW["MW<br/>videodecoder 0.2.3.0"]:::mw -. "rejected — major not aligned" .-> V["Vendor<br/>videodecoder 0.3.0.0"]:::bad
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef bad fill:#fee2e2,stroke:#b91c1c,color:#000
Undecided. One vendor server serves one major. Either every consumer moves together, or the vendor serves both majors.
Requirements: VER-3, CON-1, CON-6, CON-7, CON-8
flowchart LR
subgraph MW["MW"]
P["player<br/>0.3.0.0"]:::mw
R["recorder<br/>0.2.1.0"]:::mw
end
P -. "rejected" .-> V["Vendor<br/>videodecoder 0.2.3.0"]:::ven
R -- "ok" --> V
P -. "option: vendor also serves 0.3.x.x" .-> V3["Vendor<br/>videodecoder 0.3.0.0"]:::ven
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
style MW fill:#f8fafc,stroke:#94a3b8,color:#000
OK. The MW moves the components that are delivered and holds the rest.
Requirements: VER-3, CON-2, CON-4, CON-7, CON-8
flowchart LR
subgraph MW["MW pins"]
M1["audiodecoder 0.4.0.0 — next"]:::mw
M2["hdmicec 0.2.0.0 — held"]:::mw
end
subgraph VV["Vendor vertical"]
S1["SoC<br/>audiodecoder 0.4.0.0 — delivered"]:::ven
O1["OEM<br/>hdmicec 0.2.0.1 — 0.3.0.0 late"]:::ven
end
M1 -- "ok" --> S1
M2 -- "ok" --> O1
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
style MW fill:#f8fafc,stroke:#94a3b8,color:#000
style VV fill:#f8fafc,stroke:#94a3b8,color:#000
Undecided. Either the MW holds 0.2.x.x everywhere, or it carries both majors and selects one at runtime, or it is built per platform.
Requirements: VER-3, CON-3, CON-6, CON-7, CON-8, BLD-6
flowchart LR
subgraph MW["Common MW"]
C["videodecoder 0.2.1.0 — current"]:::mw
N["videodecoder 0.3.0.0 — next"]:::mw
end
N -- "ok" --> A["Platform A vertical<br/>videodecoder 0.3.0.0"]:::ven
C -- "ok" --> B["Platform B vertical<br/>videodecoder 0.2.3.0"]:::ven
N -. "rejected" .-> B
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
style MW fill:#f8fafc,stroke:#94a3b8,color:#000
Not supported. Both libraries export identical symbols. The first one loaded wins, silently.
Requirements: CON-5
flowchart LR
subgraph PROC["One MW process"]
H["hdmicec<br/>built against common 0.1.0.0"]:::mw
AD["audiodecoder<br/>built against common 0.2.0.0"]:::mw
end
H --> L1["libcommon-v0.1.0.0-cpp.so"]:::bad
AD --> L2["libcommon-v0.2.0.0-cpp.so"]:::bad
L1 -. "same symbols — first loaded wins" .- L2
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef bad fill:#fee2e2,stroke:#b91c1c,color:#000
style PROC fill:#f8fafc,stroke:#94a3b8,color:#000
OK. Each layer builds from its own manifest. One library per (component, version), installed to that layer's mount.
Requirements: VER-5, VER-9, BLD-1, BLD-2, BLD-5, BLD-8
%%{init: {"flowchart": {"wrappingWidth": 400}}}%%
flowchart LR
SM["SoC manifest<br/>videodecoder 0.2.2.0<br/>audiodecoder 0.3.0.0"]:::ven --> VB
OM["OEM manifest<br/>hdmicec 0.2.0.1<br/>panel 0.4.1.0"]:::ven --> VB
MM["MW manifest<br/>videodecoder 0.2.1.0<br/>audiodecoder 0.3.0.0<br/>hdmicec 0.2.0.0<br/>panel 0.4.1.0"]:::mw --> MB
VB["vendor build"] --> VL["/vendor/usr/lib<br/>libvideodecoder-v0.2.2.0-cpp.so<br/>libaudiodecoder-v0.3.0.0-cpp.so<br/>libhdmicec-v0.2.0.1-cpp.so<br/>libpanel-v0.4.1.0-cpp.so"]:::ven
MB["MW build"] --> ML["/mw/usr/lib<br/>libvideodecoder-v0.2.1.0-cpp.so<br/>libaudiodecoder-v0.3.0.0-cpp.so<br/>libhdmicec-v0.2.0.0-cpp.so<br/>libpanel-v0.4.1.0-cpp.so"]:::mw
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
OK across processes. Not supported in one process (case 13).
flowchart LR
subgraph OEM["OEM layer"]
VS["videosink<br/>imports videodecoder 0.2.0.0"]:::ven
end
subgraph SOC["SoC layer"]
VD["videodecoder 0.2.0.1"]:::ven
end
VS -- "ok over binder — separate processes" --> VD
VS -. "rejected — same process" .-> VD
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
style OEM fill:#f8fafc,stroke:#94a3b8,color:#000
style SOC fill:#f8fafc,stroke:#94a3b8,color:#000
Not supported in production. A build from current/ is unreleased and reports hash notfrozen. It is accepted only on dev images, with allowUnfrozen.
Requirements: VER-6, BLD-7, BLD-8
flowchart LR
MW["MW<br/>videodecoder 0.2.1.0"]:::mw
MW -. "rejected — production" .-> V["Vendor<br/>videodecoder current/<br/>hash notfrozen"]:::bad
MW -- "ok — dev image, allowUnfrozen" --> V
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef bad fill:#fee2e2,stroke:#b91c1c,color:#000
Not supported. The era must match.
Requirements: VER-8
flowchart LR
MW["MW<br/>videodecoder 0.2.3.0"]:::mw -. "rejected — era not aligned" .-> V["Vendor<br/>videodecoder V1"]:::bad
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef bad fill:#fee2e2,stroke:#b91c1c,color:#000
OK, in either direction. A vendor ahead serves every earlier client. An MW ahead is supported only if it implements the full stable AIDL version check and fallback in Client Usage of Stable AIDL.
Requirements: VER-7
flowchart LR
V["Vendor<br/>videodecoder V2"]:::ven
M1["MW<br/>V1"]:::mw -- "ok — vendor ahead" --> V
M2["MW<br/>V2"]:::mw -- "ok — exact" --> V
M3["MW<br/>V3"]:::mw -- "ok — MW does full AIDL version checks" --> V
classDef mw fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef ven fill:#fef3c7,stroke:#b45309,color:#000
Draft. Requirements marked Proposed are not yet agreed.
Each case above lists the requirements it shows. MUST, MUST NOT, SHOULD and MAY are as defined in RFC 2119 / RFC 8174. Status: Met: the repository does it today. Gap: required, not yet done; the issue tracks it. Proposed: a programme position not yet written into the SOP.
flowchart LR
T["Ticket<br/>Interface Effect · Priority · Milestone"] --> PR["PR<br/>one change-class label"]
PR --> B{"Breaking?"}
B -- "no" --> MI["minor bump<br/>0.2.1.0 → 0.2.2.0"]
B -- "yes" --> MA["major bump<br/>0.2.x.x → 0.3.0.0"]
MI --> AP["Approved and released"]
MA --> AP
AP --> S["Released snapshot<br/>immutable"]
MA -. "older major stays consumed" .-> PL["Planned move of every party<br/>to the new major"]
S --> R["RAG<br/>per component"]
S --> P["MW and vendor pins<br/>per layer manifest"]
P --> C{"Same major,<br/>vendor ≥ MW?"}
C -- "yes" --> OK["Runs"]
C -- "no" --> NO["Rejected by<br/>halcompat::isCompatible()"]
| ID | Requirement | UC | Status |
|---|---|---|---|
| VER-1 | Each component MUST be versioned and released independently, as 0.<major>.<minor>.<bugfix> before stable AIDL. A component's version MUST NOT move because another component changed, except through a declared import (common@0.2.0.0). |
1–3 | Met |
| VER-2 | A backwards-compatible pre-release change MUST bump minor. | 2, 3, 4, 7 | Met |
| VER-3 | A pre-release change MAY break compatibility, and MUST bump major. The new major is developed while clients keep consuming the older released major. | 5, 6, 8–12 | Met |
| VER-4 | A bugfix bump MUST NOT change the interface surface. | 3 | Met |
| VER-5 | A released snapshot <component>/<version>/ MUST NOT be modified after release. This applies to pre-release snapshots, not only to stable versions. |
14 | Met |
| VER-9 | A released snapshot MUST carry the contract only: AIDL, declared pins, hash and documentation. Its build files MUST be a symlink to the shared build, not a copy inside the snapshot. | 14 | Gap #828 |
| VER-6 | Every service MUST report its version and contract hash. A client MUST check compatibility with isCompatible() before use. An unreleased build (hash notfrozen) MUST be rejected in production. |
7–9, 16 | Met |
| VER-7 | A component MAY move to stable AIDL once its criteria are met (SOP §7). Its first stable release is V1; from then its version is an integer from V1, changes are additive only, and every client/server pairing is compatible. A client ahead of the server MUST do full version checking and fallback. |
18 | Gap #857 |
| VER-8 | A pre-release side and a stable side of the same component MUST be treated as incompatible. | 17 | Met |
| ID | Requirement | UC | Status |
|---|---|---|---|
| BLD-1 | Each layer MUST build from its own versions manifest. The manifest is identifiable and reproducible: the released cohort at a repo tag. | 14 | Met |
| BLD-2 | The closure MUST build every (component, version) a dependent links, one lib<comp>-v<ver>-cpp.so per version, installed under that layer's mount. |
14, 15 | Met |
| BLD-3 | Client and server MUST each be buildable and testable in isolation against a chosen version, without the other side or a full product build. | 1 | Met |
| BLD-4 | A common integration build MUST build MW and vendor against one baseline and call every interface over binder. | 4, 5 | Gap #817, #815 |
| BLD-5 | Each layer MUST resolve its own libraries at runtime (per-layer RUNPATH). |
14 | Met |
| BLD-6 | The alignment in CON-2 MUST be checked with halcompat::isCompatible(), so a mismatch is reported, not found by failure. |
6, 12 | Met |
| BLD-7 | Development builds (CI and merges to develop) MAY build any revision, pre-release and current/ included. They are the development cycle and release nothing. |
16 | Met |
| BLD-8 | The tip of the interface repository is not for consumption. A production build MUST consume approved, released, versioned component snapshots, chosen per component by that component's release strategy. It MUST NOT consume develop or current/. |
14, 16 | Met |
| ID | Requirement | Status |
|---|---|---|
| CHG-1 | Every change MUST start as a GitHub issue, on a branch feature/{issue}-{synopsis}, merged through a PR. |
Met |
| CHG-2 | Every PR MUST carry exactly one change-class label. The label determines the version bump. | Met |
| CHG-3 | The project's Interface Effect field (Major, CR-Major, New Interface, Minor, BugFix, Documentation, Infrastructure) MUST agree with the labels. One of the two is authoritative for the bump. | Gap #825, #827 |
| CHG-4 | A Major or CR-Major change MUST link to the adoption plan for its new major (CON-8). | Proposed |
| CHG-5 | Every programme ticket MUST carry its Jira link in the project's Jira field, and its committed date in End date. | Met |
| ID | Requirement | Status |
|---|---|---|
| RAG-1 | Every component MUST carry RED / AMBER / GREEN in metadata.yaml per SOP §4. GREEN means implementable by vendors at its current version. |
Met |
| RAG-2 | The RAG report MUST show open Major or CR changes against a GREEN component. | Gap #802 |
| RAG-3 | A major bump on a GREEN component MUST go through a new review cycle before it merges. | Met (SOP §4) |
| RAG-4 | Every RAG change MUST be diffed against the previous snapshot, so each upgrade and downgrade is explicit. | Met (daily snapshots) |