La plataforma de Android contiene muchos archivos XML para almacenar archivos de configuración
de Google Cloud (por ejemplo, configuración de audio). Muchos de los archivos en formato XML se encuentran en el archivo vendor
.
pero se leen en la partición system
. En este caso, el esquema
del archivo XML sirve como interfaz entre las dos particiones y, por lo tanto,
el esquema debe especificarse de forma explícita y debe evolucionar de manera retrocompatible
forma.
Antes de Android 10, la plataforma no proporcionaba
mecanismos que requieran la especificación y uso del esquema XML, o para evitar
cambios incompatibles en el esquema. Android 10 proporciona
este mecanismo, llamado API de
esquema de archivo de configuración. Este mecanismo consiste en una herramienta
llamada xsdc
y una regla de compilación llamada xsd_config
.
La herramienta xsdc
es un compilador de documentos de esquema XML (XSD). Analiza un archivo XSD.
al describir el esquema de un archivo XML y generar código Java y C++. El
El código generado analiza los archivos XML que se ajustan al esquema XSD en un árbol de
y cada uno de ellos modela una etiqueta XML. Los atributos XML se modelan como campos
de los objetos.
La regla de compilación xsd_config
integra la herramienta de xsdc
en el sistema de compilación.
Para un archivo de entrada XSD determinado, la regla de compilación genera bibliotecas Java y C++. Tú
puedes vincular las bibliotecas a los módulos donde los archivos XML que cumplen con el
los archivos XSD se leen y se usan. Puedes usar la regla de compilación para tus propios archivos en formato XML usados
en las particiones system
y vendor
.
API de Build Config File Schema
En esta sección, se describe cómo compilar la API de Config File Schema.
Configura la regla de compilación xsd_config en Android.bp
La regla de compilación xsd_config
genera el código del analizador con la herramienta xsdc
. El
La propiedad package_name
de la regla de compilación xsd_config
determina el nombre del paquete de
el código Java generado.
Ejemplo de regla de compilación xsd_config
en Android.bp
:
xsd_config {
name: "hal_manifest",
srcs: ["hal_manifest.xsd"],
package_name: "hal.manifest",
}
Ejemplo de estructura de directorio:
├── Android.bp
├── api
│ ├── current.txt
│ ├── last_current.txt
│ ├── last_removed.txt
│ └── removed.txt
└── hal_manifest.xsd
El sistema de compilación genera una lista de APIs usando el código Java generado y verificaciones
la API con él. Esta verificación de API se agrega a DroidCore y se ejecuta en m -j
.
Crea archivos de listas de APIs
Las verificaciones de API requieren archivos de listas de API en el código fuente.
La API enumera los archivos incluyen lo siguiente:
current.txt
yremoved.txt
comprueban si las APIs cambiaron comparando con los archivos de API generados al momento de la compilación.last_current.txt
ylast_removed.txt
comprueban si las APIs retrocompatible comparando con los archivos de la API.
Para crear los archivos de listas de la API, haz lo siguiente:
- Crear archivos de listas vacías
- Ejecuta el comando
make update-api
.
Usa el código de analizador generado
Para usar el código Java generado, agrega :
como prefijo al módulo xsd_config
.
en la propiedad srcs
de Java. El paquete del código Java generado es el
igual que la propiedad package_name
.
java_library {
name: "vintf_test_java",
srcs: [
"srcs/**/*.java"
":hal_manifest"
],
}
Para usar el código de C++ generado, agrega el nombre del módulo xsd_config
al
Propiedades generated_sources
y generated_headers
. Y agrega libxml2
a
static_libs
o shared_libs
, ya que libxml2
es obligatorio en el analizador generado
código. El espacio de nombres del
El código C++ generado es el mismo que la propiedad package_name
. Por ejemplo,
el nombre del módulo xsd_config
es hal.manifest
, el espacio de nombres es
hal::manifest
cc_library{
name: "vintf_test_cpp",
srcs: ["main.cpp"],
generated_sources: ["hal_manifest"],
generated_headers: ["hal_manifest"],
shared_libs: ["libxml2"],
}
Usa el analizador
Para usar el código del analizador de Java, usa el método XmlParser#read
El método read{class-name}
para mostrar la clase de la raíz
. En este momento, el análisis se realiza.
import hal.manifest.*;
…
class HalInfo {
public String name;
public String format;
public String optional;
…
}
void readHalManifestFromXml(File file) {
…
try (InputStream str = new BufferedInputStream(new FileInputStream(file))) {
Manifest manifest = XmlParser.read(str);
for (Hal hal : manifest.getHal()) {
HalInfo halinfo;
HalInfo.name = hal.getName();
HalInfo.format = hal.getFormat();
HalInfo.optional = hal.getOptional();
…
}
}
…
}
Para usar el código del analizador de C++, primero incluye el archivo del encabezado. El nombre del
El archivo de encabezado es el nombre del paquete con puntos (.) convertidos en guiones bajos (_).
Luego, usa el método read
o read{class-name}
para mostrar resultados.
la clase del elemento raíz. En este momento, el análisis se realiza. El valor que se devuelve es
std::optional<>
include "hal_manifest.h"
…
using namespace hal::manifest
struct HalInfo {
public std::string name;
public std::string format;
public std::string optional;
…
};
void readHalManifestFromXml(std::string file_name) {
…
Manifest manifest = *read(file_name.c_str());
for (Hal hal : manifest.getHal()) {
struct HalInfo halinfo;
HalInfo.name = hal.getName();
HalInfo.format = hal.getFormat();
HalInfo.optional = hal.getOptional();
…
}
…
}
Todas las APIs proporcionadas para usar el analizador están en api/current.txt
. Para
uniforme, todos los nombres de elementos y atributos se convierten en mayúsculas mediales (para
ejemplo, ElementName
) y se usan como la variable, el método y
el nombre de la clase. La clase del elemento raíz analizado se puede obtener con el
función read{class-name}
. Si solo hay una raíz
, el nombre de la función es read
. El valor de un subelemento analizado o
se puede obtener con el atributo get{variable-name}
.
Cómo generar código de analizador
En la mayoría de los casos, no necesitas ejecutar xsdc
directamente. Usa la compilación xsd_config
en su lugar, como se describe en
Configura la regla de compilación xsd_config en Android.bp. Esta
se explica la interfaz de línea de comandos de xsdc
, solo para completarla. Esta
puede ser útil para la depuración.
Debes proporcionar a la herramienta xsdc
la ruta de acceso al archivo XSD y un paquete. El
package es un nombre de paquete en código Java y un espacio de nombres en código C++. Opciones
Para determinar si el código generado es Java o C, son -j
o -c
.
respectivamente. La opción -o
es la ruta del directorio de salida.
usage: xsdc path/to/xsd_file.xsd [-c] [-j] [-o <arg>] [-p]
-c,--cpp Generate C++ code.
-j,--java Generate Java code.
-o,--outDir <arg> Out Directory
-p,--package Package name of the generated java file. file name of
generated C++ file and header
Comando de ejemplo:
$ xsdc audio_policy_configuration.xsd -p audio.policy -j