You can use aconfig flags in Java, C, C++, and Rust code. The AOSP build system launches a tool called aconfig used to generate a language-specific library of methods you can use to access the value of each flag. Before you can generate the library, you must declare flags and add them to the build.
Declare an aconfig flag for Java
To declare an aconfig flag for Java:
In a directory where the new code exists, create a file with the extension
.aconfig
, for example,my_new_aconfig_flag_declarations.aconfig
. An aconfig file is a text proto file that follows a standard schema.Add a flag declaration similar to the following:
package: "com.example.android.aconfig.demo.flags" container: "system" flag { name: "my_new_flag" namespace: "aconfig_demo_namespace" description: "This flag controls untested code" bug: "<none>" }
Where:
package
, when combined with the flag name, provides a unique key. In Java, settingpackage
tofoo.bar
results in an autogenerated class namedfoo.bar.Flags
. In C++, flag accessor methods would be namedfoo::bar::"flagname"
. Flags in the same declaration file belong to the same package, but multiple declaration files can contribute flags to the same package.container
defines a collection of code that is built and shipped together as a binary. Valid containers aresystem
,vendor
,system_ext
,product
,name.of.apex
, andname.of.apk
.name
contains the name of the flag containing only lowercase letters, underscores, and numbers.namespace
contains the namespace for contributions. You must work with the assigned Google reviewer to determine your namespace. If you're using feature launch flags to maintain stability of your own AOSP mirror, you can use namespace however you like.description
contains a brief description of the feature or change that is flagged.bug
is the bug number associated with the new code contribution. You must work with the assigned Google reviewer to determine yourbug
. If you're using feature launch flags to maintain stability of your own AOSP mirror, you can use your bug tracking number or use<none>
.
Save the file and exit the editor.
Set up the build
After you have declared your flag, set up the build so that it can generate the library code used to access the flag's value.
In your
Android.bp
build file, add anaconfig_declarations
section similar to the following:aconfig_declarations { name: "aconfig_demo_flags", package: "com.example.android.aconfig.demo.flags", srcs: [ "my_new_aconfig_flag_declarations.aconfig" ], }
Where:
name
contains the name of the declaration containing only lowercase letters, underscores, and numbers.package
contains the same package name used in the declaration.srcs
contains the name of the.aconfig
file where the flag is declared.
Save the file and exit the editor.
Declare an aconfig flag for C and C++
To declare an aconfig flag for C and C++:
In a directory where the new code exists, create a file with the extension
.aconfig
, for example,my_new_aconfig_flag_declarations.aconfig
. An aconfig file is a text proto file that follows a standard schema.Add a flag declaration similar to the following:
package: "com.example.android.aconfig.demo.flags" container: "system" flag { name: "my_new_flag" namespace: "aconfig_demo_namespace" description: "This flag controls untested code" bug: "<none>" }
Where:
package
, when combined with the flag name, provides a unique key. In Java, settingpackage
tofoo.bar
results in an autogenerated class namedfoo.bar.Flags
. In C++, flag accessor methods would be namedfoo::bar::"flagname"
. Flags in the same declaration file belong to the same package, but multiple declaration files can contribute flags to the same package.container
defines a collection of code that is built and shipped together as a binary. Valid containers aresystem
,vendor
,system_ext
,product
,name.of.apex
, andname.of.apk
.name
contains the name of the flag containing only lowercase letters, underscores, and numbers.namespace
contains the namespace for contributions. You must work with the assigned Google reviewer to determine your namespace. If you're using feature launch flags to maintain stability of your own AOSP mirror, you can use namespace however you like.description
contains a brief description of the feature or change that is flagged.bug
is the bug number associated with the new code contribution. You must work with the assigned Google reviewer to determine yourbug
. If you're using feature launch flags to maintain stability of your own AOSP mirror, you can use your bug tracking number or use<none>
.
Save the file and exit the editor.
Set up the build
After you have declared your flag, set up the build so that it can generate the library code used to access the flag's value.
In your
Android.bp
build file, add aaconfig_declarations
section similar to the following:aconfig_declarations { name: "aconfig_demo_flags", package: "com.example.android.aconfig.demo.flags", srcs: [ "my_new_aconfig_flag_declarations.aconfig" ], }
Where:
name
contains the name of the declaration containing only lowercase letters, underscores, and numbers.package
contains the same package name used in the declaration.srcs
contains the name of the aconfig file where the flag is declared.
In the same file, create a
cc_aconfig_library
target similar to the following:cc_aconfig_library { name: "aconfig_demo_flags_c_lib", aconfig_declarations: "aconfig_demo_flags", }
Where:
name
contains the name of the library containing only lowercase letters, underscores, and numbers.aconfig_declarations
contains the samename
used in the declaration.
The
cc_aconfig_library
build target invokes C or C++ Codegen, which creates a library with the generated code at build time.The CC aconfig library is similar to a CC library target, but has options like
vendor_available
,product_available
,host_supported
, andvndk
. If the build target depending on thiscc_aconfig_library
requires certain type of variants, you might also need to add the corresponding setting in the CC aconfig library target. For example, if the parent build target hasvendor_available
set totrue
, you might also want to setvendor_available
totrue
in thiscc_aconfig_library
target.After adding this build target, your code can access this library. You can include this library using
static_lib
orshared_lib
syntax. Note if you want to add this library as astatic_lib
, add ashared_lib
dependency onserver_configurable_flags
. Step 3 shows how to include the code generated flag library intolibexample_cpp_lib
.Create a target that uses the aconfig flags, such as the following example
cc_library
:cc_library { name: "libexample_cpp_lib", srcs: ["src/example_cpp_lib.cc"], double_loadable: true, cflags: [ "-Wall", "-Werror", "-Wno-unused-function", "-Wno-unused-parameter", ], header_libs: [ "jni_headers", ], shared_libs: [ "server_configurable_flags", ], static_libs: [ "aconfig_demo_flags_c_lib", ], export_include_dirs: ["src/include"], }
Where:
shared_libs
includes extra dependencies required for aconfig flags.static_libs
is the name of library that is created by the build per thecc_aconfig_library
name
field in step 2. By creating acc_library
entry with the static library name, you can now use the aconfig flags in your code.
Declare an aconfig flag for Rust
To declare an aconfig flag for Rust:
In a directory where the new code exists, create a file with the extension
.aconfig
, for example,my_new_aconfig_flag_declarations.aconfig
. An aconfig file is a text proto file that follows a standard schema.Add a flag declaration similar to the following:
package: "com.example.android.aconfig.demo.flags" container: "system" flag { name: "my_new_flag" namespace: "aconfig_demo_namespace" description: "This flag controls untested code" bug: "<none>" }
Where:
package
, when combined with the flag name, provides a unique key. In Java, settingpackage
tofoo.bar
results in an autogenerated class namedfoo.bar.Flags
. In C++, flag accessor methods would be namedfoo::bar::"flagname"
. Flags in the same declaration file belong to the same package, but multiple declaration files can contribute flags to the same package.container
defines a collection of code that is built and shipped together as a binary. Valid containers aresystem
,vendor
,system_ext
,product
,name.of.apex
, andname.of.apk
.name
contains the name of the flag containing only lowercase letters, underscores, and numbers.namespace
contains the namespace for contributions. You must work with the assigned Google reviewer to determine your namespace. If you're using feature launch flags to maintain stability of your own AOSP mirror, you can use namespace however you like.description
contains a brief description of the feature or change that is flagged.bug
is the bug number associated with the new code contribution. You must work with the assigned Google reviewer to determine yourbug
. If you're using feature launch flags to maintain stability of your own AOSP mirror, you can use your bug tracking number or use<none>
.
Save the file and exit the editor.
Set up the build
After you have declared your flag, set up the build so that it can generate the library code used to access the flag's value.
In your
Android.bp
build file, add aaconfig_declarations
section similar to the following:aconfig_declarations { name: "aconfig_demo_flags", package: "com.example.android.aconfig.demo.flags", srcs: [ "my_new_aconfig_flag_declarations.aconfig" ], }
Where:
name
contains the name of the declaration containing only lowercase letters, underscores, and numbers.package
contains the same package name used in the declaration.srcs
contains the name of the aconfig file where the flag is declared.
Create a
rust_aconfig_library
target similar to the next example. This target invokes Rust Codegen and creates a Rust library with the generated code during build time.rust_aconfig_library { name: "libaconfig_demo_flags_rust", crate_name: "aconfig_demo_flags_rust", aconfig_declarations: "aconfig_demo_flags", }
Where:
name
contains the name of the declaration containing only lowercase letters, underscores, and numbers.crate_name
contains the same package name used in the declaration.aconfig_declarations
contains the samename
used in the declaration.
With this change, your code can depend on this Rust library.
In the same file, create a
rust_library
entry similar to the following:rust_library { name: "libexample_lib", rustlibs: [ "libaconfig_demo_flags_rust", ] }
This sample allows your source code build targets
libexample_demo_flags_rust
to include the code generated flag library.Save the file and exit the editor.