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