কনফিগ ফাইল স্কিমা API বাস্তবায়ন করা হচ্ছে

অ্যান্ড্রয়েড প্ল্যাটফর্মে কনফিগার ডেটা সংরক্ষণের জন্য অনেকগুলি XML ফাইল রয়েছে (উদাহরণস্বরূপ, অডিও কনফিগারেশন)। অনেক XML ফাইল vendor পার্টিশনে আছে, কিন্তু সেগুলি system পার্টিশনে পড়া হয়। এই ক্ষেত্রে, XML ফাইলের স্কিমা দুটি পার্টিশন জুড়ে ইন্টারফেস হিসাবে কাজ করে, এবং সেইজন্য স্কিমাটি অবশ্যই স্পষ্টভাবে নির্দিষ্ট করা উচিত এবং একটি পশ্চাদমুখী-সামঞ্জস্যপূর্ণ পদ্ধতিতে বিকশিত হওয়া আবশ্যক।

অ্যান্ড্রয়েড 10-এর আগে, প্ল্যাটফর্মটি XML স্কিমা নির্দিষ্ট করার এবং ব্যবহার করার জন্য বা স্কিমাতে অসঙ্গতিপূর্ণ পরিবর্তনগুলি প্রতিরোধ করার জন্য ব্যবস্থা প্রদান করেনি। অ্যান্ড্রয়েড 10 কনফিগ ফাইল স্কিমা API নামে পরিচিত এই প্রক্রিয়াটি সরবরাহ করে। এই প্রক্রিয়াটি xsdc নামক একটি টুল এবং xsd_config নামক একটি বিল্ড নিয়ম নিয়ে গঠিত।

xsdc টুল হল একটি XML স্কিমা ডকুমেন্ট (XSD) কম্পাইলার। এটি একটি XSD ফাইল পার্স করে একটি XML ফাইলের স্কিমা বর্ণনা করে এবং জাভা এবং C++ কোড তৈরি করে। জেনারেট করা কোড XML ফাইলগুলিকে পার্স করে যেগুলি XSD স্কিমার সাথে সামঞ্জস্যপূর্ণ বস্তুর একটি গাছে পরিণত হয়, যার প্রতিটি মডেল একটি XML ট্যাগ। XML বৈশিষ্ট্যগুলি বস্তুর ক্ষেত্র হিসাবে মডেল করা হয়।

xsd_config বিল্ড নিয়ম xsdc টুলকে বিল্ড সিস্টেমে একীভূত করে। একটি প্রদত্ত XSD ইনপুট ফাইলের জন্য, বিল্ড নিয়ম জাভা এবং C++ লাইব্রেরি তৈরি করে। আপনি লাইব্রেরিগুলিকে মডিউলগুলির সাথে লিঙ্ক করতে পারেন যেখানে XSD-এর সাথে সঙ্গতিপূর্ণ XML ফাইলগুলি পড়া এবং ব্যবহার করা হয়। আপনি system এবং vendor পার্টিশন জুড়ে ব্যবহৃত আপনার নিজস্ব XML ফাইলগুলির জন্য বিল্ড নিয়ম ব্যবহার করতে পারেন।

বিল্ডিং কনফিগ ফাইল স্কিমা API

এই বিভাগে কনফিগ ফাইল স্কিমা API কীভাবে তৈরি করা যায় তা বর্ণনা করে।

Android.bp-এ xsd_config বিল্ড নিয়ম কনফিগার করা হচ্ছে

xsd_config বিল্ড নিয়ম xsdc টুলের সাথে পার্সার কোড তৈরি করে। xsd_config বিল্ড নিয়মের package_name বৈশিষ্ট্য জেনারেট করা জাভা কোডের প্যাকেজ নাম নির্ধারণ করে।

Android.bpxsd_config বিল্ড নিয়মের উদাহরণ:

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 তালিকা তৈরি করে এবং এটির বিরুদ্ধে API চেক করে। এই API চেকটি DroidCore-এ যোগ করা হয়েছে এবং m -j এ কার্যকর করা হয়েছে।

API তালিকা ফাইল তৈরি করা

এপিআই চেকের জন্য সোর্স কোডে এপিআই তালিকা ফাইলের প্রয়োজন হয়।

API তালিকাভুক্ত ফাইলগুলির মধ্যে রয়েছে:

  • current.txt এবং removed.txt বিল্ড টাইমে জেনারেট করা এপিআই ফাইলের সাথে তুলনা করে এপিআই পরিবর্তন করা হয়েছে কিনা তা পরীক্ষা করুন।
  • last_current.txt এবং last_removed.txt এপিআই ফাইলগুলির সাথে তুলনা করে APIগুলি পিছিয়ে সামঞ্জস্যপূর্ণ কিনা তা পরীক্ষা করুন।

API তালিকা ফাইল তৈরি করতে:

  1. খালি তালিকা ফাইল তৈরি করুন.
  2. make update-api কমান্ডটি চালান।

উত্পন্ন পার্সার কোড ব্যবহার করে

জেনারেট করা জাভা কোড ব্যবহার করতে, জাভা srcs প্রপার্টিতে xsd_config মডিউল নামের উপসর্গ হিসেবে : যোগ করুন। জেনারেট করা জাভা কোডের প্যাকেজ package_name বৈশিষ্ট্যের মতোই।

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

জেনারেটেড C++ কোড ব্যবহার করতে, generated_sources এবং generated_headers বৈশিষ্ট্যে xsd_config মডিউল নাম যোগ করুন। এবং static_libs বা shared_libslibxml2 যোগ করুন, যেহেতু জেনারেট করা পার্সার কোডে 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"],
}

পার্সার ব্যবহার করে

জাভা পার্সার কোড ব্যবহার করতে, রুট এলিমেন্টের ক্লাস রিটার্ন করতে 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 or 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();
        …
    }
    …
}

পার্সার ব্যবহার করার জন্য প্রদত্ত সমস্ত APIs api/current.txt এ রয়েছে। অভিন্নতার জন্য, সমস্ত উপাদান এবং বৈশিষ্ট্যের নাম উটের ক্ষেত্রে রূপান্তরিত হয় (উদাহরণস্বরূপ, ElementName ) এবং সংশ্লিষ্ট পরিবর্তনশীল, পদ্ধতি এবং শ্রেণির নাম হিসাবে ব্যবহৃত হয়। পার্স করা রুট এলিমেন্টের ক্লাসটি read{ class-name } ফাংশন ব্যবহার করে পাওয়া যেতে পারে। যদি শুধুমাত্র একটি মূল উপাদান থাকে, তাহলে ফাংশনের নামটি read হয়। একটি পার্স করা সাবলিমেন্ট বা অ্যাট্রিবিউটের মান get{ variable-name } ফাংশন ব্যবহার করে প্রাপ্ত করা যেতে পারে।

পার্সার কোড তৈরি করা হচ্ছে

বেশিরভাগ ক্ষেত্রে, আপনাকে সরাসরি xsdc চালানোর দরকার নেই। পরিবর্তে xsd_config বিল্ড নিয়ম ব্যবহার করুন, যেমনটি Android.bp-এ xsd_config বিল্ড নিয়ম কনফিগারিং- এ বর্ণিত হয়েছে। এই বিভাগটি xsdc কমান্ড লাইন ইন্টারফেস ব্যাখ্যা করে, শুধুমাত্র সম্পূর্ণতার জন্য। এটি ডিবাগিংয়ের জন্য দরকারী হতে পারে।

আপনাকে অবশ্যই xsdc টুলটিকে XSD ফাইলের পথ এবং একটি প্যাকেজ দিতে হবে। প্যাকেজটি জাভা কোডে একটি প্যাকেজ নাম এবং 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