README.md
1# Android Audio Flagging Guide
2
3This directory contains the aconfig flag definitions and the associated build files for Android
4Audio features.
5
6## Build Configuration
7
8### Namespaces
9
10There are several global namespaces involved with flagging which must be maintained:
11 - **Mendel project**: `media_audio`. Associated with mdb group and used by gantry.
12All aconfig flags in this namespace should be defined in this directory, and all flags defined in
13this directory should belong to this namespace.
14 - **Blueprint namespaces**: the name field of any module is unique over a particular build
15namespace (for platform development purposes there is one).
16 - **Aconfig package**: All flags generated by aconfig are converted by Halyard into Mendel flags
17of the form {PACKAGE}{FLAG}, where both fields are stripped of spaces, underscores and dashes. This
18combo **must** be globally unique (across Android).
19 - **Generated code**: Both java and cpp aconfig library rules generate code which pollutes the
20namespace of the backend. This means that if two aconfig java libraries exist which consume **any**
21`aconfig_declarations` with packages which intersect, these libraries are incompatible to be linked
22together (and equivalent in cc). If the library is included in the framework, it is on the
23bootclasspath, so no other library for that package can exist. Additionally, the cpp backend
24generates header files with the same name as the unqualified name of the package which means
25include path conflicts are possible.
26
27
28### Naming convention
29
30Given above, follow the following naming convention (given a `{PACKAGE}`).
31
32Generally, `aconfig_declarations` and `{backend}_aconfig_library` should be 1-1, except in cases
33where different package configurations are needed with pre-processing with different classpaths.
34This is because multiple libraries with the same aconfig package cannot compile together.
35
36```
37aconfig_declarations {
38 name: "{PACKAGE}-aconfig",
39 package: "{PACKAGE}",
40 srcs: ["{PACKAGE}.aconfig"]
41}
42
43{backend}_aconfig_library {
44 name: "{PACKAGE}-aconfig-{backend}",
45 aconfig_declarations: "{PACKAGE}-aconfig",
46 defaults: ["audio-aconfig-{backend}-defaults"],
47}
48
49```
50If the flags are required as part of the framework, the java backend is ingested into the framework
51via srcjar for cyclic dependency/simplicity reasons. Add the following
52
53```
54 ":{PACKAGE}-aconfig-java{.generated_srcjars}"
55```
56
57as a source in `audio-framework-aconfig`. This target is included in the file-list which compiles
58the framework. If a lib is included in this list, it is unecessary to add it in any other blueprint
59file for platform code (for non-host). For tests, the library should be **statically** linked
60(which shadows the bootclasspath), to get around @hide restrictions (this approach may change).
61
62
63### Visibility
64
65Visibility should be controlled (private) so that flag cleanup remains maintainable by the team.
66This constraints the locations where extant flags need to be chased for removal.
67
68
69### Packaging preference
70As a rule, prefer the most constrained package appropriate for a particular flag. This limits viral
71dependencies on a flag library which restricts where/how testing can occur. It also speeds up
72incremental rebuilds. Packages which end up in the framework should be avoided as much as possible,
73since they require rebuilding the framework, pollute the bootclasspath, and require special build
74handling to operate (srcjar generation, jarjar to access in CTS).
75
76Utilize "java-like" package naming for all packages, to ensure packages are globally unique, and
77to avoid class conflicts if these flags are later included in java code.
78
79## Workflow
80
81### Usage Style
82In general, prefer flags at the integration level, rather than at the implementation level.
83This allows flags to be queried in as few locations as possible such as by (parametrizing functions,
84classes, types, etc.) It also allows callers to make different decisions on when behavior can/should
85be changed (e.g. different flags could be used for different libraries). This follows dependency
86injection principles and ensures that global state has a smaller blast radius, and also makes it
87easier to test code by relying less on infrastructure. The more places a flag is queried, the more
88its implementation should be deferred upwards, either by the injection interfaces, or by explicit
89parametrization.
90
91### Flag scope
92In general, flags should be scoped as precisely as possible while retaining orthogonality. If
93flags are too specific (multiple flags interact together to encompass a single change), then
94reasoning about independently switching flags becomes difficult. Other than all-on and all-of
95configurations, there is limited soak for flag combinations, so it is critical that flags
96interact with each other minimally (although emergent properties are inevitable).
97However, if flags are too general, graduating/reverting flags can carry too much behavior change,
98the build graph degenerates, and
99
100### Instant Staging
101In general, it is recommended that the moment a flag is added to the tree, it should be moved to
102staging on gantry. There is no benefit to adding a flag but not moving into staging.
103This allows:
1041. Verification by treehugger in both pre/post-submit
1051. Automatic configuration for feature development for local engineering workflows
1061. Integration with other engineering features in development
107
108
109### FlaggedApi
110FlaggedApi operates differently than other types of flags since these flags only graduate at the
111next API bump. These flags also must be exposed through the framework. FlaggedApis should only
112operate over the same set of flags as an implementation if the implementation is entirely related
113to the feature. Given the constraints on the flag lifetime, it is preferable to use a "regular"
114flag for implementation, which can integrate/soak/ship/clean-up faster.
115
116Additionally, unlike "regular" flags, @FlaggedApis are not effectively soaked, so like non-trunk
117API development, they are heavily reliant on CTS to integrate.
118
119On non-next configs, @FlaggedApi has no runtime control, but it is undefined for callers to
120call a FlaggedApi without querying the status of the flag. The build itself is not changed on
121staging. Anything which builds against the platform can see all @FlaggedApis.
122
123Methods annotated FlaggedApis are changed for release finalization -- if an API is not in next,
124it is stripped from the Sdk (and left @hide). If an API graduated to next, it is included fully
125included in the Sdk, and the @FlaggedApi annotation is stripped.
126
127
128### TestApis
129TestApis do not require flagging, since their existence in the tree implies that they should
130be accessible to callers (xTS not building on trunk enables this).
131
132
133### Api Changes
134Currently, the flag infra does not support any type of Api modification (arguments, annotation,
135renaming, deletion, etc.) In any of these cases (including for SystemApi), exceptions will need to
136be granted.
137