A plataforma Android contém muitos arquivos XML para armazenar configurações
(por exemplo, configuração de áudio). Muitos dos arquivos XML estão no arquivo vendor
mas são lidas na partição system
. Nesse caso, o esquema
do arquivo XML serve como interface entre as duas partições. Assim,
o esquema precisa ser especificado explicitamente e evoluir em um ambiente compatível com
forma
Antes do Android 10, a plataforma não fornecia
que exijam a especificação e o uso do esquema XML ou para evitar
e alterações incompatíveis no esquema. O Android 10 oferece
desse mecanismo, chamado API Config File Schema. Esse mecanismo consiste em uma ferramenta
chamada xsdc
e uma regra de build chamada xsd_config
.
A ferramenta xsdc
é um compilador de documento de esquema XML (XSD, na sigla em inglês). Ele analisa um arquivo XSD
que descreve o esquema de um arquivo XML e gera código Java e C++. A
o código gerado analisa arquivos XML que estão em conformidade com o esquema XSD em uma árvore de
objetos, cada um modelando uma tag XML. Os atributos XML são modelados como campos
dos objetos.
A regra de build xsd_config
integra a ferramenta xsdc
ao sistema de build.
Para um determinado arquivo de entrada XSD, a regra de compilação gera bibliotecas Java e C++. Você
pode vincular as bibliotecas aos módulos em que os arquivos XML estão em conformidade com o
o XSD é lido e usado. Você pode usar a regra de build para seus próprios arquivos XML usados
nas partições system
e vendor
.
API Build Config File Schema
Nesta seção, descrevemos como criar a API Config File Schema.
Configurar a regra de build xsd_config em Android.bp
A regra de build xsd_config
gera o código do analisador com a ferramenta xsdc
. A
A propriedade package_name
da regra de build xsd_config
determina o nome do pacote
o código Java gerado.
Exemplo de regra de build xsd_config
em Android.bp
:
xsd_config {
name: "hal_manifest",
srcs: ["hal_manifest.xsd"],
package_name: "hal.manifest",
}
Exemplo de estrutura de diretórios:
├── Android.bp
├── api
│ ├── current.txt
│ ├── last_current.txt
│ ├── last_removed.txt
│ └── removed.txt
└── hal_manifest.xsd
O sistema de build gera uma lista de APIs usando o código Java gerado e verifica
a API em relação a ele. Essa verificação de API é adicionada ao DroidCore e executada em m -j
.
Criar arquivos de listas de APIs
As verificações de API exigem arquivos de listas da API no código-fonte.
Os arquivos de listas da API incluem:
current.txt
eremoved.txt
verificam se as APIs são modificadas comparando com os arquivos de API gerados no tempo de build.last_current.txt
elast_removed.txt
verificam se as APIs estão compatíveis com versões anteriores em comparação com os arquivos de API.
Para criar os arquivos de listas da API:
- Crie arquivos de listas vazias.
- Execute o comando
make update-api
.
Usar o código do analisador gerado
Para usar o código Java gerado, adicione :
como um prefixo ao módulo xsd_config
.
na propriedade srcs
do Java. O pacote do código Java gerado é o
igual à propriedade package_name
.
java_library {
name: "vintf_test_java",
srcs: [
"srcs/**/*.java"
":hal_manifest"
],
}
Para usar o código em C++ gerado, adicione o nome do módulo xsd_config
ao
Propriedades generated_sources
e generated_headers
. E adicionar libxml2
a
static_libs
ou shared_libs
, já que libxml2
é obrigatório no analisador gerado.
o código-fonte. O namespace do elemento
o código C++ gerado é o mesmo que a propriedade package_name
. Por exemplo, se
o nome do módulo xsd_config
for hal.manifest
, o namespace será
hal::manifest
cc_library{
name: "vintf_test_cpp",
srcs: ["main.cpp"],
generated_sources: ["hal_manifest"],
generated_headers: ["hal_manifest"],
shared_libs: ["libxml2"],
}
Usar o analisador
Para usar o código do analisador Java, use o XmlParser#read
ou
método read{class-name}
para retornar a classe da raiz
. A análise acontece no momento.
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 o código de analisador C++, inclua primeiro o arquivo principal. O nome
arquivo principal é o nome do pacote com pontos (.) convertidos em sublinhados (_).
Em seguida, use o método read
ou read{class-name}
para retornar
a classe do elemento raiz. A análise acontece no momento. O valor de retorno é
um 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 as APIs fornecidas para usar o analisador estão em api/current.txt
. Para
uniformidade, todos os nomes de elementos e atributos são convertidos para camelCase (por
exemplo, ElementName
) e usada como a variável, o método e o
nome da classe. A classe do elemento raiz analisado pode ser obtida usando-se o
função read{class-name}
. Se houver apenas uma raiz
o nome da função será read
. O valor de um subelemento analisado ou
pode ser acessado usando o get{variable-name}
função.
Gerar código do analisador
Na maioria dos casos, você não precisa executar xsdc
diretamente. Usar o build xsd_config
regra, conforme descrito nas
Como configurar a regra de build xsd_config em Android.bp. Isso
explica a interface de linha de comando xsdc
, apenas para fins de integridade. Isso
podem ser úteis para depuração.
Forneça à ferramenta xsdc
o caminho para o arquivo XSD e um pacote. A
package é um nome de pacote no código Java e um namespace no código C++. As opções
para determinar se o código gerado é Java ou C são -j
ou -c
,
respectivamente. A opção -o
é o caminho do diretório de saída.
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
Exemplo de comando:
$ xsdc audio_policy_configuration.xsd -p audio.policy -j