ใช้ API สคีมาไฟล์กำหนดค่า

แพลตฟอร์ม Android มีไฟล์ XML จำนวนมากสำหรับจัดเก็บข้อมูลการกําหนดค่า (เช่น การกําหนดค่าเสียง) ไฟล์ XML จำนวนมากอยู่ในพาร์ติชัน vendor แต่ระบบจะอ่านไฟล์เหล่านั้นในพาร์ติชัน system ในกรณีนี้ สคีมาของไฟล์ XML จะทำหน้าที่เป็นอินเทอร์เฟซระหว่าง 2 พาร์ติชัน ดังนั้นจึงต้องระบุสคีมาอย่างชัดเจนและต้องพัฒนาให้ใช้งานย้อนหลังได้

ก่อนที่จะมี Android 10 แพลตฟอร์มไม่มีกลไกในการกำหนดให้ระบุและใช้สคีมา XML หรือป้องกันการเปลี่ยนแปลงที่สอดคล้องกันไม่ได้ในสคีมา Android 10 มีกลไกนี้ที่เรียกว่า Config File Schema API กลไกนี้ประกอบไปด้วยเครื่องมือชื่อ xsdc และกฎบิลด์ xsd_config

เครื่องมือ xsdc คือคอมไพเลอร์เอกสารสคีมา XML (XSD) โดยจะแยกวิเคราะห์ไฟล์ XSD ที่อธิบายสคีมาของไฟล์ XML และสร้างโค้ด Java และ C++ โค้ดที่สร้างขึ้นจะแยกวิเคราะห์ไฟล์ XML ที่เป็นไปตามสคีมา XSD เป็นต้นไม้ของออบเจ็กต์ ซึ่งแต่ละออบเจ็กต์จะจำลองแท็ก XML แอตทริบิวต์ XML อยู่ในรูปแบบช่องของออบเจ็กต์

กฎการสร้าง xsd_config จะผสานรวมเครื่องมือ xsdc เข้ากับระบบการสร้าง สำหรับไฟล์อินพุต XSD หนึ่งๆ กฎการสร้างจะสร้างไลบรารี Java และ C++ คุณสามารถลิงก์ไลบรารีกับโมดูลที่อ่านและใช้ไฟล์ XML ที่เป็นไปตาม XSD ได้ คุณจะใช้กฎของบิลด์สำหรับไฟล์ XML ของคุณเองที่ใช้ทั่วทั้งพาร์ติชัน system และ vendor ได้

Build Config File Schema API

ส่วนนี้จะอธิบายวิธีสร้าง API สคีมาไฟล์การกำหนดค่า

กำหนดค่ากฎบิลด์ xsd_config ใน Android.bp

กฎการสร้าง xsd_config จะสร้างโค้ดโปรแกรมแยกวิเคราะห์ด้วยเครื่องมือ xsdc พร็อพเพอร์ตี้ package_name ของxsd_configกฎการสร้างจะกำหนดชื่อแพ็กเกจของโค้ด Java ที่สร้างขึ้น

ตัวอย่างกฎการสร้าง xsd_config ใน Android.bp

xsd_config {
    name
: "hal_manifest",
    srcs
: ["hal_manifest.xsd"],
    package_name
: "hal.manifest",
}

ตัวอย่างโครงสร้างไดเรกทอรี

├── Android.bp
├── api
  ├── current.txt
  ├── last_current.txt
  ├── last_removed.txt
  └── removed.txt
└── hal_manifest.xsd

ระบบบิลด์จะสร้างรายการ API โดยใช้โค้ด Java ที่สร้างขึ้น และตรวจสอบ API กับรายการดังกล่าว การตรวจสอบ API นี้จะเพิ่มลงใน DroidCore และดำเนินการในเวลา m -j

สร้างไฟล์รายการ API

การตรวจสอบ API กำหนดให้ไฟล์ API แสดงอยู่ในซอร์สโค้ด

ไฟล์ที่ API แสดง ได้แก่

  • current.txt และ removed.txt จะตรวจสอบว่า API มีการเปลี่ยนแปลงหรือไม่โดยเปรียบเทียบกับไฟล์ API ที่สร้างขึ้น ณ เวลาที่สร้าง
  • last_current.txt และ last_removed.txt จะตรวจสอบว่า API ใช้งานย้อนหลังได้หรือไม่โดยเปรียบเทียบกับไฟล์ API

วิธีสร้างไฟล์รายการ API

  1. สร้างไฟล์รายการที่ว่างเปล่า
  2. เรียกใช้คำสั่ง make update-api

ใช้โค้ดโปรแกรมแยกวิเคราะห์ที่สร้างขึ้น

หากต้องการใช้โค้ด Java ที่สร้างขึ้น ให้เพิ่ม : เป็นคำนำหน้าให้กับชื่อโมดูล xsd_config ในพร็อพเพอร์ตี้ srcs ของ Java แพ็กเกจโค้ด Java ที่สร้างขึ้นจะเหมือนกับพร็อพเพอร์ตี้ package_name

java_library {
    name
: "vintf_test_java",
    srcs
: [
       
"srcs/**/*.java"
       
":hal_manifest"
   
],
}

หากต้องการใช้โค้ด C++ ที่สร้างขึ้น ให้เพิ่มชื่อโมดูล xsd_config ลงในพร็อพเพอร์ตี้ generated_sources และ generated_headers และเพิ่ม libxml2 ไปยัง static_libs หรือ shared_libs เนื่องจากจำเป็นต้องใช้ libxml2 ในโค้ดโปรแกรมแยกวิเคราะห์ที่สร้างขึ้น เนมสเปซของโค้ด C++ ที่สร้างขึ้นจะเหมือนกับพร็อพเพอร์ตี้ package_name เช่น หากชื่อโมดูล xsd_config คือ hal.manifest เนมสเปซก็จะเป็น hal::manifest

cc_library{
    name
: "vintf_test_cpp",
    srcs
: ["main.cpp"],
    generated_sources
: ["hal_manifest"],
    generated_headers
: ["hal_manifest"],
    shared_libs
: ["libxml2"],
}

ใช้โปรแกรมแยกวิเคราะห์

หากต้องการใช้โค้ดโปรแกรมแยกวิเคราะห์ Java ให้ใช้เมธอด XmlParser#read หรือ read{class-name} เพื่อแสดงผลคลาสขององค์ประกอบรูท แยกวิเคราะห์ ณ เวลานี้

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();
           

       
}
   
}
   

}

หากต้องการใช้โค้ดแยกวิเคราะห์ C++ ให้รวมไฟล์ส่วนหัวก่อน ชื่อของไฟล์ส่วนหัวคือชื่อแพ็กเกจที่มีเครื่องหมายจุด (.) ซึ่งแปลงเป็นขีดล่าง (_) จากนั้นใช้เมธอด read หรือ read{class-name} เพื่อแสดงผลคลาสขององค์ประกอบรูท แยกวิเคราะห์ ณ เวลานี้ ผลลัพธ์คือ 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();
       

   
}
   

}

API ทั้งหมดที่ระบุไว้เพื่อใช้โปรแกรมแยกวิเคราะห์อยู่ใน api/current.txt ชื่อองค์ประกอบและแอตทริบิวต์ทั้งหมดจะแปลงเป็นตัวอักษรพิมพ์เล็ก-ใหญ่ (เช่น ElementName) และใช้เป็นตัวแปร เมธอด และชื่อคลาสที่สอดคล้องกันเพื่อให้มีความสอดคล้องกัน คุณดูคลาสขององค์ประกอบรูทที่แยกวิเคราะห์ได้โดยใช้ฟังก์ชัน read{class-name} หากมีองค์ประกอบรูทเพียงรายการเดียว ชื่อฟังก์ชันจะเป็น read คุณดูค่าขององค์ประกอบย่อยหรือแอตทริบิวต์ที่แยกวิเคราะห์แล้วได้โดยใช้ฟังก์ชัน get{variable-name}

สร้างโค้ดโปรแกรมแยกวิเคราะห์

ในกรณีส่วนใหญ่ คุณไม่จําเป็นต้องเรียกใช้ xsdc โดยตรง ให้ใช้xsd_configกฎการสร้างแทน ตามที่อธิบายไว้ในการกำหนดค่ากฎการสร้าง xsd_config ใน Android.bp ส่วนนี้จะอธิบายอินเทอร์เฟซบรรทัดคำสั่ง xsdc เพื่อไม่ให้ขาดข้อมูล การดำเนินการนี้อาจเป็นประโยชน์สำหรับการแก้ไขข้อบกพร่อง

คุณต้องกำหนดเส้นทางไปยังไฟล์ XSD และแพ็กเกจให้เครื่องมือ xsdc แพ็กเกจคือชื่อแพ็กเกจในโค้ด Java และเนมสเปซในโค้ด C++ ตัวเลือกสำหรับกำหนดว่าโค้ดที่สร้างขึ้นคือ Java หรือ C จะเป็น -j หรือ -c ตามลำดับ ตัวเลือก -o คือเส้นทางของไดเรกทอรีเอาต์พุต

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

ตัวอย่างคําสั่ง

$ xsdc audio_policy_configuration.xsd -p audio.policy -j