Platform Android berisi banyak file XML untuk menyimpan data konfigurasi (misalnya, konfigurasi audio). Banyak file XML berada di partisi vendor
, namun dibaca di partisi system
. Dalam hal ini, skema file XML berfungsi sebagai antarmuka di kedua partisi, dan oleh karena itu skema harus ditentukan secara eksplisit dan harus berkembang dengan cara yang kompatibel ke belakang.
Sebelum Android 10, platform tidak menyediakan mekanisme yang mengharuskan penentuan dan penggunaan skema XML, atau untuk mencegah perubahan skema yang tidak kompatibel. Android 10 menyediakan mekanisme ini, yang disebut Config File Schema API. Mekanisme ini terdiri dari alat yang disebut xsdc
dan aturan build yang disebut xsd_config
.
Alat xsdc
adalah kompiler Dokumen Skema XML (XSD). Ini mem-parsing file XSD yang menjelaskan skema file XML dan menghasilkan kode Java dan C++. Kode yang dihasilkan mem-parsing file XML yang sesuai dengan skema XSD menjadi pohon objek, yang masing-masing memodelkan tag XML. Atribut XML dimodelkan sebagai bidang objek.
Aturan build xsd_config
mengintegrasikan alat xsdc
ke dalam sistem build. Untuk file masukan XSD tertentu, aturan build menghasilkan pustaka Java dan C++. Anda dapat menautkan perpustakaan ke modul tempat file XML yang sesuai dengan XSD dibaca dan digunakan. Anda dapat menggunakan aturan build untuk file XML Anda sendiri yang digunakan di seluruh partisi system
dan vendor
.
Membangun API Skema File Konfigurasi
Bagian ini menjelaskan cara membuat Config File Schema API.
Mengonfigurasi aturan build xsd_config di Android.bp
Aturan build xsd_config
menghasilkan kode parser dengan alat xsdc
. Properti package_name
aturan build xsd_config
menentukan nama paket kode Java yang dihasilkan.
Contoh aturan build xsd_config
di Android.bp
:
xsd_config {
name: "hal_manifest",
srcs: ["hal_manifest.xsd"],
package_name: "hal.manifest",
}
Contoh struktur direktori:
├── Android.bp
├── api
│ ├── current.txt
│ ├── last_current.txt
│ ├── last_removed.txt
│ └── removed.txt
└── hal_manifest.xsd
Sistem pembangunan menghasilkan daftar API menggunakan kode Java yang dihasilkan dan memeriksa API terhadapnya. Pemeriksaan API ini ditambahkan ke DroidCore dan dijalankan di m -j
.
Membuat file daftar API
Pemeriksaan API memerlukan file daftar API dalam kode sumber.
File daftar API meliputi:
-
current.txt
danremoved.txt
memeriksa apakah API diubah dengan membandingkan dengan file API yang dihasilkan pada waktu pembuatan. -
last_current.txt
danlast_removed.txt
memeriksa apakah API tersebut kompatibel dengan versi sebelumnya dengan membandingkannya dengan file API.
Untuk membuat file daftar API:
- Buat file daftar kosong.
- Jalankan perintah
make update-api
.
Menggunakan kode parser yang dihasilkan
Untuk menggunakan kode Java yang dihasilkan, tambahkan :
sebagai awalan pada nama modul xsd_config
di properti Java srcs
. Paket kode Java yang dihasilkan sama dengan properti package_name
.
java_library {
name: "vintf_test_java",
srcs: [
"srcs/**/*.java"
":hal_manifest"
],
}
Untuk menggunakan kode C++ yang dihasilkan, tambahkan nama modul xsd_config
ke properti generated_sources
dan generated_headers
. Dan tambahkan libxml2
ke static_libs
atau shared_libs
, karena libxml2
diperlukan dalam kode parser yang dihasilkan. Namespace kode C++ yang dihasilkan sama dengan properti package_name
. Misalnya, jika nama modul xsd_config
adalah hal.manifest
, namespacenya adalah hal::manifest
.
cc_library{
name: "vintf_test_cpp",
srcs: ["main.cpp"],
generated_sources: ["hal_manifest"],
generated_headers: ["hal_manifest"],
shared_libs: ["libxml2"],
}
Menggunakan pengurai
Untuk menggunakan kode parser Java, gunakan metode XmlParser#read
atau read{ class-name }
untuk mengembalikan kelas elemen root. Parsing terjadi saat ini.
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();
…
}
}
…
}
Untuk menggunakan kode parser C++, sertakan file header terlebih dahulu. Nama file header adalah nama paket dengan titik (.) yang diubah menjadi garis bawah (_). Kemudian gunakan metode read
atau read{ class-name }
untuk mengembalikan kelas elemen root. Parsing terjadi saat ini. Nilai yang dikembalikan adalah 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();
…
}
…
}
Semua API yang disediakan untuk menggunakan parser ada di api/current.txt
. Untuk keseragaman, semua nama elemen dan atribut diubah menjadi huruf unta (misalnya, ElementName
) dan digunakan sebagai variabel, metode, dan nama kelas yang sesuai. Kelas elemen akar yang diurai dapat diperoleh dengan menggunakan fungsi read{ class-name }
. Jika hanya ada satu elemen root, maka nama fungsinya adalah read
. Nilai subelemen atau atribut yang diurai dapat diperoleh dengan menggunakan fungsi get{ variable-name }
.
Menghasilkan kode parser
Dalam kebanyakan kasus, Anda tidak perlu menjalankan xsdc
secara langsung. Gunakan aturan build xsd_config
sebagai gantinya, seperti dijelaskan dalam Mengonfigurasi aturan build xsd_config di Android.bp . Bagian ini menjelaskan antarmuka baris perintah xsdc
, hanya untuk kelengkapan. Ini mungkin berguna untuk debugging.
Anda harus memberikan alat xsdc
jalur ke file XSD, dan sebuah paket. Paket adalah nama paket dalam kode Java dan namespace dalam kode C++. Opsi untuk menentukan apakah kode yang dihasilkan adalah Java atau C masing-masing adalah -j
atau -c
. Opsi -o
adalah jalur direktori keluaran.
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
Contoh perintah:
$ xsdc audio_policy_configuration.xsd -p audio.policy -j