এইচএএল-এর জন্য এআইডিএল

অ্যান্ড্রয়েড ১১ অ্যান্ড্রয়েডে HAL-এর জন্য AIDL ব্যবহারের ক্ষমতা প্রবর্তন করে, যার ফলে HIDL ছাড়াই অ্যান্ড্রয়েডের কিছু অংশ বাস্তবায়ন করা সম্ভব হয়। সম্ভব হলে HAL-গুলিকে একচেটিয়াভাবে AIDL ব্যবহারে রূপান্তর করুন (যখন আপস্ট্রিম HAL-গুলি HIDL ব্যবহার করে, তখন HIDL ব্যবহার করতে হবে)।

যে HAL গুলি AIDL ব্যবহার করে system.img এর মতো ফ্রেমওয়ার্ক উপাদান এবং vendor.img এর মতো হার্ডওয়্যার উপাদানের মধ্যে যোগাযোগ করতে পারে, তাদের অবশ্যই স্থিতিশীল AIDL ব্যবহার করতে হবে। তবে, একটি পার্টিশনের মধ্যে যোগাযোগ করার জন্য, উদাহরণস্বরূপ, একটি HAL থেকে অন্য HAL-এ, IPC মেকানিজম ব্যবহারের উপর কোনও বিধিনিষেধ নেই।

প্রেরণা

AIDL HIDL এর চেয়ে অনেক বেশি সময় ধরে ব্যবহৃত হচ্ছে এবং এটি অন্যান্য অনেক জায়গায় ব্যবহার করা হচ্ছে, যেমন অ্যান্ড্রয়েড ফ্রেমওয়ার্ক উপাদানগুলির মধ্যে বা অ্যাপগুলিতে। এখন যেহেতু AIDL এর স্থিতিশীলতা সমর্থন রয়েছে, তাই একটি একক IPC রানটাইম দিয়ে একটি সম্পূর্ণ স্ট্যাক বাস্তবায়ন করা সম্ভব। AIDL এর HIDL এর চেয়েও ভালো সংস্করণ ব্যবস্থা রয়েছে। AIDL এর কিছু সুবিধা এখানে দেওয়া হল:

  • একটি একক IPC ভাষা ব্যবহার করার অর্থ হল শেখা, ডিবাগ করা, অপ্টিমাইজ করা এবং সুরক্ষিত করার জন্য কেবল একটি জিনিস থাকা।
  • AIDL একটি ইন্টারফেসের মালিকদের জন্য ইন-প্লেস ভার্সনিং সমর্থন করে:
    • মালিকরা ইন্টারফেসের শেষে পদ্ধতি যোগ করতে পারেন, অথবা পার্সেলেবলে ক্ষেত্র যোগ করতে পারেন। এর অর্থ হল বছরের পর বছর ধরে কোড সংস্করণ করা সহজ হয়, এবং বছরের পর বছর খরচও কম হয় (টাইপগুলি জায়গায় সংশোধন করা যেতে পারে এবং প্রতিটি ইন্টারফেস সংস্করণের জন্য অতিরিক্ত লাইব্রেরির প্রয়োজন হয় না)।
    • এক্সটেনশন ইন্টারফেসগুলি টাইপ সিস্টেমের পরিবর্তে রান টাইমে সংযুক্ত করা যেতে পারে, তাই ইন্টারফেসের নতুন সংস্করণগুলিতে ডাউনস্ট্রিম এক্সটেনশনগুলি রিবেস করার কোনও প্রয়োজন নেই।
  • একটি বিদ্যমান AIDL ইন্টারফেস সরাসরি ব্যবহার করা যেতে পারে যখন এর মালিক এটিকে স্থিতিশীল করতে চান। আগে, ইন্টারফেসের একটি সম্পূর্ণ কপি HIDL-এ তৈরি করতে হত।

AIDL রানটাইমের বিপরীতে তৈরি করুন

AIDL-এর তিনটি ভিন্ন ব্যাকএন্ড আছে: Java, NDK, এবং CPP। স্থিতিশীল AIDL ব্যবহার করতে, সর্বদা system/lib*/libbinder.solibbinder এর সিস্টেম কপি ব্যবহার করুন এবং /dev/binder এ কথা বলুন। vendor ছবিতে কোডের জন্য, এর অর্থ হল libbinder (VNDK থেকে) ব্যবহার করা যাবে না: এই লাইব্রেরিতে একটি অস্থির C++ API এবং অস্থির ইন্টার্নাল রয়েছে। পরিবর্তে, নেটিভ বিক্রেতার কোডে AIDL-এর NDK ব্যাকএন্ড, libbinder_ndk এর সাথে লিঙ্ক (যা সিস্টেম libbinder.so দ্বারা সমর্থিত) এবং aidl_interface এন্ট্রি দ্বারা তৈরি NDK লাইব্রেরির সাথে লিঙ্ক ব্যবহার করতে হবে। সঠিক মডিউল নামের জন্য, মডিউল নামকরণের নিয়ম দেখুন।

একটি AIDL HAL ইন্টারফেস লিখুন

সিস্টেম এবং বিক্রেতার মধ্যে একটি AIDL ইন্টারফেস ব্যবহার করার জন্য, ইন্টারফেসে দুটি পরিবর্তন প্রয়োজন:

  • প্রতিটি ধরণের সংজ্ঞা @VintfStability দিয়ে টীকাবদ্ধ করতে হবে।
  • aidl_interface ঘোষণায় stability: "vintf", .

শুধুমাত্র একটি ইন্টারফেসের মালিকই এই পরিবর্তনগুলি করতে পারেন।

যখন আপনি এই পরিবর্তনগুলি করবেন, তখন ইন্টারফেসটি কাজ করার জন্য VINTF ম্যানিফেস্টে থাকা আবশ্যক। Vendor Test Suite (VTS) test vts_treble_vintf_vendor_test ব্যবহার করে এটি (এবং সম্পর্কিত প্রয়োজনীয়তা, যেমন প্রকাশিত ইন্টারফেসগুলি হিমায়িত কিনা তা যাচাই করা) পরীক্ষা করুন। আপনি এই প্রয়োজনীয়তা ছাড়াই একটি @VintfStability ইন্টারফেস ব্যবহার করতে পারেন NDK ব্যাকএন্ডে AIBinder_forceDowngradeToLocalStability , C++ ব্যাকএন্ডে android::Stability::forceDowngradeToLocalStability , অথবা জাভা ব্যাকএন্ডে android.os.Binder#forceDowngradeToSystemStability কল করে একটি বাইন্ডার অবজেক্ট অন্য কোনও প্রক্রিয়ায় পাঠানোর আগে।

অতিরিক্তভাবে, সর্বাধিক কোড পোর্টেবিলিটির জন্য এবং অপ্রয়োজনীয় অতিরিক্ত লাইব্রেরির মতো সম্ভাব্য সমস্যা এড়াতে, CPP ব্যাকএন্ডটি অক্ষম করুন।

কোডটি দেখায় কিভাবে CPP ব্যাকএন্ড নিষ্ক্রিয় করতে হয়:

    aidl_interface: {
        ...
        backend: {
            cpp: {
                enabled: false,
            },
        },
    }

AIDL HAL ইন্টারফেস খুঁজুন

HALS-এর জন্য AOSP স্থিতিশীল AIDL ইন্টারফেসগুলি HIDL ইন্টারফেসের মতো একই বেস ডিরেক্টরিতে aidl ফোল্ডারের মধ্যে থাকে:

  • hardware/interfaces হল হার্ডওয়্যার দ্বারা সরবরাহিত ইন্টারফেসের জন্য।
  • frameworks/hardware/interfaces হল হার্ডওয়্যারে প্রদত্ত উচ্চ-স্তরের ইন্টারফেসের জন্য।
  • system/hardware/interfaces হল হার্ডওয়্যারে প্রদত্ত নিম্ন-স্তরের ইন্টারফেসের জন্য।

এক্সটেনশন ইন্টারফেসগুলিকে vendor বা hardware অন্যান্য hardware/interfaces সাবডিরেক্টরিতে রাখুন।

এক্সটেনশন ইন্টারফেস

প্রতিটি রিলিজের সাথে অ্যান্ড্রয়েডের কিছু অফিসিয়াল AOSP ইন্টারফেস থাকে। যখন অ্যান্ড্রয়েড পার্টনাররা এই ইন্টারফেসগুলিতে ক্ষমতা যোগ করতে চায়, তখন তাদের সরাসরি এগুলি পরিবর্তন করা উচিত নয় কারণ এটি তাদের অ্যান্ড্রয়েড রানটাইমকে AOSP অ্যান্ড্রয়েড রানটাইমের সাথে সামঞ্জস্যপূর্ণ করে না। GSI ইমেজটি কাজ চালিয়ে যেতে পারে তাই এই ইন্টারফেসগুলি পরিবর্তন করা এড়িয়ে চলুন।

এক্সটেনশন দুটি ভিন্ন উপায়ে নিবন্ধন করতে পারে:

তবে একটি এক্সটেনশন নিবন্ধিত হলেও, যখন বিক্রেতা-নির্দিষ্ট (অর্থাৎ আপস্ট্রিম AOSP-এর অংশ নয়) উপাদানগুলি ইন্টারফেস ব্যবহার করে, তখন মার্জ দ্বন্দ্ব সম্ভব হয় না। যাইহোক, যখন আপস্ট্রিম AOSP উপাদানগুলিতে ডাউনস্ট্রিম পরিবর্তন করা হয়, তখন মার্জ দ্বন্দ্ব দেখা দিতে পারে এবং নিম্নলিখিত কৌশলগুলি সুপারিশ করা হয়:

  • পরবর্তী রিলিজে AOSP-তে ইন্টারফেস সংযোজনগুলি আপস্ট্রিম করুন।
  • আপস্ট্রিম ইন্টারফেস সংযোজন যা পরবর্তী রিলিজে আরও নমনীয়তা (মার্জ দ্বন্দ্ব ছাড়াই) প্রদান করে।

এক্সটেনশন পার্সেবল: পার্সেবলহোল্ডার

ParcelableHolder হল Parcelable ইন্টারফেসের একটি উদাহরণ যেখানে Parcelable এর আরেকটি উদাহরণ থাকতে পারে।

ParcelableHolder এর প্রধান ব্যবহার হল Parcelable এক্সটেনসিবল করা। উদাহরণস্বরূপ, ডিভাইস বাস্তবায়নকারীরা AOSP-সংজ্ঞায়িত Parcelable , AospDefinedParcelable তাদের ভ্যালু-অ্যাড বৈশিষ্ট্যগুলি অন্তর্ভুক্ত করার জন্য প্রসারিত করতে সক্ষম হবে বলে আশা করে এমন একটি চিত্র।

আপনার ভ্যালু-অ্যাড বৈশিষ্ট্যগুলির সাথে Parcelable প্রসারিত করতে ParcelableHolder ইন্টারফেস ব্যবহার করুন। ParcelableHolder ইন্টারফেসে Parcelable এর একটি উদাহরণ রয়েছে। আপনি যদি সরাসরি Parcelable এ ক্ষেত্রগুলি যুক্ত করার চেষ্টা করেন, তাহলে এটি একটি ত্রুটি ঘটায়:

parcelable AospDefinedParcelable {
  int a;
  String b;
  String x; // ERROR: added by a device implementer
  int[] y; // added by a device implementer
}

পূর্ববর্তী কোডে যেমন দেখা গেছে, এই অনুশীলনটি ভেঙে গেছে কারণ ডিভাইস ইমপ্লিমেন্টার দ্বারা যোগ করা ক্ষেত্রগুলি অ্যান্ড্রয়েডের পরবর্তী রিলিজে Parcelable সংশোধন করার সময় দ্বন্দ্ব দেখা দিতে পারে।

ParcelableHolder ব্যবহার করে, একটি parcelable এর মালিক Parcelable এর একটি উদাহরণে একটি এক্সটেনশন পয়েন্ট সংজ্ঞায়িত করতে পারেন:

parcelable AospDefinedParcelable {
  int a;
  String b;
  ParcelableHolder extension;
}

তারপর ডিভাইস বাস্তবায়নকারীরা তাদের এক্সটেনশনের জন্য তাদের নিজস্ব Parcelable ইনস্ট্যান্স সংজ্ঞায়িত করতে পারে:

parcelable OemDefinedParcelable {
  String x;
  int[] y;
}

নতুন Parcelable ইনস্ট্যান্সটি ParcelableHolder ফিল্ডের সাহায্যে মূল Parcelable এর সাথে সংযুক্ত করা যেতে পারে:


// Java
AospDefinedParcelable ap = ...;
OemDefinedParcelable op = new OemDefinedParcelable();
op.x = ...;
op.y = ...;

ap.extension.setParcelable(op);

...

OemDefinedParcelable op = ap.extension.getParcelable(OemDefinedParcelable.class);

// C++
AospDefinedParcelable ap;
OemDefinedParcelable op;
std::shared_ptr<OemDefinedParcelable> op_ptr = make_shared<OemDefinedParcelable>();

ap.extension.setParcelable(op);
ap.extension.setParcelable(op_ptr);

...

std::shared_ptr<OemDefinedParcelable> op_ptr;

ap.extension.getParcelable(&op_ptr);

// NDK
AospDefinedParcelable ap;
OemDefinedParcelable op;
ap.extension.setParcelable(op);

...

std::optional<OemDefinedParcelable> op;
ap.extension.getParcelable(&op);

// Rust
let mut ap = AospDefinedParcelable { .. };
let op = Rc::new(OemDefinedParcelable { .. });

ap.extension.set_parcelable(Rc::clone(&op));

...

let op = ap.extension.get_parcelable::<OemDefinedParcelable>();

AIDL HAL সার্ভারের উদাহরণের নাম

প্রচলিত নিয়ম অনুসারে, AIDL HAL পরিষেবাগুলির একটি ইনস্ট্যান্স নাম $package.$type/$instance ফর্ম্যাটের হয়। উদাহরণস্বরূপ, ভাইব্রেটর HAL-এর একটি ইনস্ট্যান্স android.hardware.vibrator.IVibrator/default হিসাবে নিবন্ধিত।

একটি AIDL HAL সার্ভার লিখুন

@VintfStability AIDL সার্ভারগুলিকে VINTF ম্যানিফেস্টে ঘোষণা করতে হবে, উদাহরণস্বরূপ:

    <hal format="aidl">
        <name>android.hardware.vibrator</name>
        <version>1</version>
        <fqname>IVibrator/default</fqname>
    </hal>

অন্যথায়, তাদের স্বাভাবিকভাবে একটি AIDL পরিষেবা নিবন্ধন করা উচিত। VTS পরীক্ষা চালানোর সময়, আশা করা হয় যে সমস্ত ঘোষিত AIDL HAL উপলব্ধ থাকবে।

একটি AIDL ক্লায়েন্ট লিখুন

AIDL ক্লায়েন্টদের অবশ্যই সামঞ্জস্যতা ম্যাট্রিক্সে নিজেদের ঘোষণা করতে হবে, উদাহরণস্বরূপ:

    <hal format="aidl" optional="true">
        <name>android.hardware.vibrator</name>
        <version>1-2</version>
        <interface>
            <name>IVibrator</name>
            <instance>default</instance>
        </interface>
    </hal>

একটি বিদ্যমান HAL কে HIDL থেকে AIDL এ রূপান্তর করুন

HIDL ইন্টারফেসকে AIDL-এ রূপান্তর করতে hidl2aidl টুলটি ব্যবহার করুন।

hidl2aidl বৈশিষ্ট্য:

  • প্রদত্ত প্যাকেজের জন্য HAL ( .hal ) ফাইলের উপর ভিত্তি করে AIDL ( .aidl ) ফাইল তৈরি করুন।
  • নতুন তৈরি AIDL প্যাকেজের জন্য সমস্ত ব্যাকএন্ড সক্রিয় করে বিল্ড নিয়ম তৈরি করুন।
  • HIDL টাইপ থেকে AIDL টাইপে অনুবাদের জন্য জাভা, CPP এবং NDK ব্যাকএন্ডে অনুবাদ পদ্ধতি তৈরি করুন।
  • প্রয়োজনীয় নির্ভরতা সহ অনুবাদ লাইব্রেরির জন্য বিল্ড নিয়ম তৈরি করুন।
  • CPP এবং NDK ব্যাকএন্ডে HIDL এবং AIDL গণনাকারীদের একই মান নিশ্চিত করার জন্য স্ট্যাটিক অ্যাসেট তৈরি করুন।

HAL ফাইলের প্যাকেজকে AIDL ফাইলে রূপান্তর করতে এই পদক্ষেপগুলি অনুসরণ করুন:

  1. system/tools/hidl/hidl2aidl এ অবস্থিত টুলটি তৈরি করুন।

    সর্বশেষ উৎস থেকে এই টুলটি তৈরি করলে সবচেয়ে সম্পূর্ণ অভিজ্ঞতা পাওয়া যাবে। পূর্ববর্তী রিলিজ থেকে পুরোনো শাখাগুলিতে ইন্টারফেস রূপান্তর করতে আপনি সর্বশেষ সংস্করণটি ব্যবহার করতে পারেন:

    m hidl2aidl
  2. রূপান্তরিত করার জন্য প্যাকেজের পরে একটি আউটপুট ডিরেক্টরি দিয়ে টুলটি কার্যকর করুন।

    ঐচ্ছিকভাবে, সমস্ত জেনারেট করা ফাইলের উপরে একটি নতুন লাইসেন্স ফাইলের বিষয়বস্তু যোগ করতে -l আর্গুমেন্ট ব্যবহার করুন। সঠিক লাইসেন্স এবং তারিখ ব্যবহার করতে ভুলবেন না:

    hidl2aidl -o <output directory> -l <file with license> <package>

    উদাহরণস্বরূপ:

    hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
  3. তৈরি করা ফাইলগুলি পড়ুন এবং রূপান্তরের সাথে যেকোনো সমস্যা সমাধান করুন:

    • conversion.log এ এমন কোনও সমস্যা আছে যা সমাধান করা সম্ভব নয়।
    • তৈরি করা AIDL ফাইলগুলিতে সতর্কতা এবং পরামর্শ থাকতে পারে যার জন্য পদক্ষেপ নেওয়া প্রয়োজন। এই মন্তব্যগুলি // দিয়ে শুরু হয়।
    • প্যাকেজটি পরিষ্কার করুন এবং উন্নতি করুন।
    • @JavaDerive প্রয়োজনীয় বৈশিষ্ট্যগুলির জন্য টীকাটি পরীক্ষা করুন, যেমন toString অথবা equals
  4. আপনার প্রয়োজনীয় লক্ষ্যমাত্রাগুলিই তৈরি করুন:

    • ব্যবহার করা হবে না এমন ব্যাকএন্ড অক্ষম করুন। CPP ব্যাকএন্ডের চেয়ে NDK ব্যাকএন্ডকে অগ্রাধিকার দিন; AIDL রানটাইমের বিপরীতে Build দেখুন।
    • অনুবাদ লাইব্রেরি বা তাদের তৈরি করা কোড যা ব্যবহার করা হবে না তা সরিয়ে ফেলুন।
  5. AIDL এবং HIDL এর মধ্যে প্রধান পার্থক্যগুলি দেখুন:

    • AIDL-এর অন্তর্নির্মিত Status এবং ব্যতিক্রমগুলি ব্যবহার করলে সাধারণত ইন্টারফেস উন্নত হয় এবং অন্য ইন্টারফেস-নির্দিষ্ট স্ট্যাটাস ধরণের প্রয়োজনীয়তা দূর হয়।
    • পদ্ধতিতে AIDL ইন্টারফেস আর্গুমেন্টগুলি HIDL-এর মতো ডিফল্টরূপে @nullable হয় না।

AIDL HAL-এর জন্য SEPolicy

একটি AIDL পরিষেবার ধরণ যা বিক্রেতা কোডে দৃশ্যমান, তার hal_service_type বৈশিষ্ট্য থাকতে হবে। অন্যথায়, sepolicy কনফিগারেশনটি অন্য যেকোনো AIDL পরিষেবার মতোই হবে (যদিও HAL-এর জন্য বিশেষ বৈশিষ্ট্য রয়েছে)। HAL পরিষেবার প্রেক্ষাপটের একটি উদাহরণ সংজ্ঞা এখানে দেওয়া হল:

    type hal_foo_service, service_manager_type, hal_service_type;

প্ল্যাটফর্ম দ্বারা সংজ্ঞায়িত বেশিরভাগ পরিষেবার জন্য, সঠিক ধরণের একটি পরিষেবা প্রসঙ্গ ইতিমধ্যেই যোগ করা হয়েছে (উদাহরণস্বরূপ, android.hardware.foo.IFoo/default ইতিমধ্যেই hal_foo_service হিসাবে চিহ্নিত)। তবে, যদি একটি ফ্রেমওয়ার্ক ক্লায়েন্ট একাধিক ইনস্ট্যান্স নাম সমর্থন করে, তাহলে ডিভাইস-নির্দিষ্ট service_contexts ফাইলগুলিতে অতিরিক্ত ইনস্ট্যান্স নাম যোগ করতে হবে:

    android.hardware.foo.IFoo/custom_instance u:object_r:hal_foo_service:s0

যখন আপনি একটি নতুন ধরণের HAL তৈরি করেন, তখন আপনাকে HAL বৈশিষ্ট্য যোগ করতে হবে। একটি নির্দিষ্ট HAL বৈশিষ্ট্য একাধিক পরিষেবা ধরণের সাথে যুক্ত হতে পারে (যার প্রতিটিতে একাধিক উদাহরণ থাকতে পারে যেমনটি আলোচনা করা হয়েছে)। একটি HAL, foo এর জন্য, hal_attribute(foo) আছে। এই ম্যাক্রো hal_foo_client এবং hal_foo_server বৈশিষ্ট্যগুলিকে সংজ্ঞায়িত করে। একটি প্রদত্ত ডোমেনের জন্য, hal_client_domain এবং hal_server_domain ম্যাক্রোগুলি একটি ডোমেনকে একটি প্রদত্ত HAL বৈশিষ্ট্যের সাথে সংযুক্ত করে। উদাহরণস্বরূপ, এই HAL এর ক্লায়েন্ট হওয়া সিস্টেম সার্ভার hal_client_domain(system_server, hal_foo) নীতির সাথে সামঞ্জস্যপূর্ণ। একটি HAL সার্ভার একইভাবে hal_server_domain(my_hal_domain, hal_foo) অন্তর্ভুক্ত করে।

সাধারণত, একটি নির্দিষ্ট HAL অ্যাট্রিবিউটের জন্য, রেফারেন্স বা উদাহরণ HAL-এর জন্য hal_foo_default এর মতো একটি ডোমেন তৈরি করুন। তবে, কিছু ডিভাইস তাদের নিজস্ব সার্ভারের জন্য এই ডোমেনগুলি ব্যবহার করে। একাধিক সার্ভারের জন্য ডোমেনগুলির মধ্যে পার্থক্য করা কেবল তখনই গুরুত্বপূর্ণ যখন একই ইন্টারফেস পরিবেশন করে এমন একাধিক সার্ভার থাকে এবং তাদের বাস্তবায়নে একটি ভিন্ন অনুমতি সেটের প্রয়োজন হয়। এই সমস্ত ম্যাক্রোতে, hal_foo একটি sepolicy অবজেক্ট নয়। পরিবর্তে, এই টোকেনটি এই ম্যাক্রোগুলি দ্বারা একটি ক্লায়েন্ট সার্ভার জোড়ার সাথে সম্পর্কিত অ্যাট্রিবিউটের গ্রুপকে উল্লেখ করার জন্য ব্যবহার করা হয়।

তবে, এখনও পর্যন্ত, hal_foo_service এবং hal_foo ( hal_attribute(foo) থেকে অ্যাট্রিবিউট জোড়া) সংযুক্ত নয়। একটি HAL অ্যাট্রিবিউট hal_attribute_service ম্যাক্রো ব্যবহার করে AIDL HAL পরিষেবার সাথে যুক্ত করা হয় (HIDL HAL গুলি hal_attribute_hwservice ম্যাক্রো ব্যবহার করে), উদাহরণস্বরূপ, hal_attribute_service(hal_foo, hal_foo_service) । এর অর্থ হল hal_foo_client প্রক্রিয়াগুলি HAL-এর নিয়ন্ত্রণ নিতে পারে এবং hal_foo_server প্রক্রিয়াগুলি HAL-কে নিবন্ধন করতে পারে। এই নিবন্ধন নিয়মগুলির প্রয়োগ কনটেক্সট ম্যানেজার ( servicemanager ) দ্বারা করা হয়।

পরিষেবার নামগুলি সবসময় HAL বৈশিষ্ট্যের সাথে সঙ্গতিপূর্ণ নাও হতে পারে, উদাহরণস্বরূপ, hal_attribute_service(hal_foo, hal_foo2_service) । সাধারণভাবে, যেহেতু এর অর্থ হল পরিষেবাগুলি সর্বদা একসাথে ব্যবহৃত হয়, আপনি hal_foo2_service টি সরিয়ে সমস্ত পরিষেবা প্রসঙ্গে hal_foo_service ব্যবহার করতে পারেন। যখন HAL একাধিক hal_attribute_service উদাহরণ সেট করে, তখন এর কারণ হল মূল HAL বৈশিষ্ট্যের নামটি যথেষ্ট সাধারণ নয় এবং পরিবর্তন করা যায় না।

সবকিছু একসাথে করলে, HAL এর একটি উদাহরণ এইরকম দেখাচ্ছে:

    public/attributes:
    // define hal_foo, hal_foo_client, hal_foo_server
    hal_attribute(foo)

    public/service.te
    // define hal_foo_service
    type hal_foo_service, hal_service_type, protected_service, service_manager_type

    public/hal_foo.te:
    // allow binder connection from client to server
    binder_call(hal_foo_client, hal_foo_server)
    // allow client to find the service, allow server to register the service
    hal_attribute_service(hal_foo, hal_foo_service)
    // allow binder communication from server to service_manager
    binder_use(hal_foo_server)

    private/service_contexts:
    // bind an AIDL service name to the selinux type
    android.hardware.foo.IFooXxxx/default u:object_r:hal_foo_service:s0

    private/<some_domain>.te:
    // let this domain use the hal service
    binder_use(some_domain)
    hal_client_domain(some_domain, hal_foo)

    vendor/<some_hal_server_domain>.te
    // let this domain serve the hal service
    hal_server_domain(some_hal_server_domain, hal_foo)

সংযুক্ত এক্সটেনশন ইন্টারফেস

যেকোনো বাইন্ডার ইন্টারফেসের সাথে একটি এক্সটেনশন সংযুক্ত করা যেতে পারে, তা সে সার্ভিস ম্যানেজারের সাথে সরাসরি নিবন্ধিত একটি শীর্ষ-স্তরের ইন্টারফেস হোক বা এটি একটি সাব-ইন্টারফেস। এক্সটেনশন পাওয়ার সময়, আপনাকে অবশ্যই নিশ্চিত করতে হবে যে এক্সটেনশনের ধরণটি প্রত্যাশা অনুযায়ী। আপনি শুধুমাত্র বাইন্ডার পরিবেশনকারী প্রক্রিয়া থেকে এক্সটেনশন সেট করতে পারেন।

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

একটি বাইন্ডারে একটি এক্সটেনশন সেট করতে, নিম্নলিখিত API গুলি ব্যবহার করুন:

  • NDK ব্যাকএন্ড: AIBinder_setExtension
  • জাভা ব্যাকএন্ড: android.os.Binder.setExtension
  • সিপিপি ব্যাকএন্ড: android::Binder::setExtension
  • মরিচা ব্যাকএন্ড: binder::Binder::set_extension

একটি বাইন্ডারে একটি এক্সটেনশন পেতে, নিম্নলিখিত API গুলি ব্যবহার করুন:

  • NDK ব্যাকএন্ড: AIBinder_getExtension
  • জাভা ব্যাকএন্ড: android.os.IBinder.getExtension
  • CPP ব্যাকএন্ড: android::IBinder::getExtension
  • মরিচা ব্যাকএন্ড: binder::Binder::get_extension

এই API গুলির জন্য আরও তথ্য আপনি সংশ্লিষ্ট ব্যাকএন্ডে getExtension ফাংশনের ডকুমেন্টেশনে পেতে পারেন। এক্সটেনশনগুলি কীভাবে ব্যবহার করবেন তার একটি উদাহরণ হল hardware/interfaces/tests/extension/vibrator

AIDL এবং HIDL এর প্রধান পার্থক্য

AIDL HAL ব্যবহার করার সময় অথবা AIDL HAL ইন্টারফেস ব্যবহার করার সময়, HIDL HAL লেখার সাথে তুলনা করে পার্থক্যগুলি সম্পর্কে সচেতন থাকুন।

  • AIDL ভাষার সিনট্যাক্স জাভার কাছাকাছি। HIDL সিনট্যাক্স C++ এর মতো।
  • সকল AIDL ইন্টারফেসে বিল্ট-ইন এরর স্ট্যাটাস থাকে। কাস্টম স্ট্যাটাস টাইপ তৈরি করার পরিবর্তে, ইন্টারফেস ফাইলগুলিতে ধ্রুবক স্ট্যাটাস ইনট তৈরি করুন এবং CPP এবং NDK ব্যাকএন্ডে EX_SERVICE_SPECIFIC এবং জাভা ব্যাকএন্ডে ServiceSpecificException ব্যবহার করুন। Error handling দেখুন।
  • বাইন্ডার অবজেক্ট পাঠানো হলে AIDL স্বয়ংক্রিয়ভাবে থ্রেড পুল শুরু করে না। আপনাকে অবশ্যই সেগুলি ম্যানুয়ালি শুরু করতে হবে ( থ্রেড ম্যানেজমেন্ট দেখুন)।
  • AIDL অনির্বাচিত পরিবহন ত্রুটিগুলিতে বাতিল করে না (HIDL অনির্বাচিত ত্রুটিগুলিতে Return করে)।
  • AIDL প্রতিটি ফাইলের জন্য শুধুমাত্র একটি প্রকার ঘোষণা করতে পারে।
  • AIDL আর্গুমেন্টগুলি আউটপুট প্যারামিটার ছাড়াও in , out , অথবা inout হিসাবে নির্দিষ্ট করা যেতে পারে (কোনও সিঙ্ক্রোনাস কলব্যাক নেই)।
  • AIDL handle এর পরিবর্তে আদিম টাইপ হিসেবে fd ব্যবহার করে।
  • HIDL অসঙ্গত পরিবর্তনের জন্য প্রধান সংস্করণ এবং সামঞ্জস্যপূর্ণ পরিবর্তনের জন্য গৌণ সংস্করণ ব্যবহার করে। AIDL-তে, পশ্চাদপট-সামঞ্জস্যপূর্ণ পরিবর্তনগুলি স্থানেই করা হয়। AIDL-এর প্রধান সংস্করণগুলির কোনও স্পষ্ট ধারণা নেই; পরিবর্তে, এটি প্যাকেজের নামগুলিতে অন্তর্ভুক্ত করা হয়েছে। উদাহরণস্বরূপ, AIDL প্যাকেজ নাম bluetooth2 ব্যবহার করতে পারে।
  • AIDL ডিফল্টরূপে রিয়েলটাইম অগ্রাধিকার উত্তরাধিকার পায় না। রিয়েলটাইম অগ্রাধিকার উত্তরাধিকার সক্ষম করতে প্রতি বাইন্ডারে setInheritRt ফাংশন ব্যবহার করতে হবে।

HAL-এর জন্য পরীক্ষা

এই বিভাগটি HAL পরীক্ষার জন্য সর্বোত্তম অনুশীলনগুলি বর্ণনা করে। আপনার HAL এর ইন্টিগ্রেশন পরীক্ষা VTS তে না থাকলেও এই অনুশীলনগুলি বৈধ।

প্রত্যাশিত HAL বাস্তবায়ন যাচাই করার জন্য Android VTS-এর উপর নির্ভর করে। VTS নিশ্চিত করতে সাহায্য করে যে Android পুরানো বিক্রেতা বাস্তবায়নের সাথে সামঞ্জস্যপূর্ণ হতে পারে। VTS ব্যর্থ বাস্তবায়নের ক্ষেত্রে পরিচিত সামঞ্জস্যের সমস্যা রয়েছে যা ভবিষ্যতের OS সংস্করণগুলির সাথে কাজ করতে বাধা দিতে পারে।

HAL-এর জন্য VTS-এর দুটি প্রধান অংশ রয়েছে।

১. ডিভাইসে থাকা HAL গুলি Android দ্বারা পরিচিত এবং প্রত্যাশিত কিনা তা যাচাই করুন।

অ্যান্ড্রয়েড সমস্ত ইনস্টল করা HAL-এর একটি স্থির, নির্ভুল তালিকার উপর নির্ভর করে। এই তালিকাটি VINTF ম্যানিফেস্টে প্রকাশ করা হয়েছে। বিশেষ, প্ল্যাটফর্ম-ব্যাপী পরীক্ষাগুলি সমগ্র সিস্টেমে HAL স্তরগুলির অখণ্ডতা যাচাই করে। HAL-নির্দিষ্ট কোনও পরীক্ষা লেখার আগে, আপনার এই পরীক্ষাগুলিও চালানো উচিত, কারণ তারা বলতে পারে যে HAL-এর VINTF কনফিগারেশনগুলি অসঙ্গত কিনা।

এই পরীক্ষার সেটটি test/vts-testcase/hal/treble/vintf -এ পাওয়া যাবে। যদি আপনি কোনও ভেন্ডর HAL বাস্তবায়নের উপর কাজ করেন, তাহলে এটি যাচাই করতে vts_treble_vintf_vendor_test ব্যবহার করুন। আপনি atest vts_treble_vintf_vendor_test কমান্ড দিয়ে এই পরীক্ষাটি চালাতে পারেন।

এই পরীক্ষাগুলি যাচাই করার জন্য দায়ী:

  • VINTF ম্যানিফেস্টে ঘোষিত প্রতিটি @VintfStability ইন্টারফেস একটি পরিচিত প্রকাশিত সংস্করণে হিমায়িত করা হয়। এটি ইন্টারফেসের উভয় পক্ষই ইন্টারফেসের সেই সংস্করণের সঠিক সংজ্ঞায় একমত কিনা তা যাচাই করে। এটি মৌলিক ক্রিয়াকলাপের জন্য প্রয়োজনীয়।
  • VINTF ম্যানিফেস্টে ঘোষিত সমস্ত HAL গুলি সেই ডিভাইসে উপলব্ধ। ঘোষিত HAL পরিষেবা ব্যবহারের জন্য পর্যাপ্ত অনুমতিপ্রাপ্ত যেকোনো ক্লায়েন্টকে যেকোনো সময় সেই পরিষেবাগুলি পেতে এবং ব্যবহার করতে সক্ষম হতে হবে।
  • VINTF ম্যানিফেস্টে ঘোষিত সমস্ত HAL গুলি ম্যানিফেস্টে ঘোষিত ইন্টারফেসের সংস্করণটি পরিবেশন করছে।
  • কোনও ডিভাইসে কোনও অবচিত HAL পরিবেশিত হচ্ছে না। FCM লাইফসাইকেলে বর্ণিত HAL ইন্টারফেসের নিম্ন সংস্করণগুলির জন্য Android সমর্থন বন্ধ করে দেয়।
  • ডিভাইসটিতে প্রয়োজনীয় HAL গুলি উপস্থিত আছে। Android সঠিকভাবে কাজ করার জন্য কিছু HAL গুলি প্রয়োজন।

2. প্রতিটি HAL-এর প্রত্যাশিত আচরণ যাচাই করুন

প্রতিটি HAL ইন্টারফেসের নিজস্ব VTS পরীক্ষা থাকে যা তার ক্লায়েন্টদের কাছ থেকে প্রত্যাশিত আচরণ যাচাই করে। পরীক্ষার কেসগুলি ঘোষিত HAL ইন্টারফেসের প্রতিটি উদাহরণের বিরুদ্ধে চলে এবং বাস্তবায়িত ইন্টারফেসের সংস্করণের উপর ভিত্তি করে নির্দিষ্ট আচরণ প্রয়োগ করে।

C++ এ, আপনি libaidlvintf_gtest_helperandroid::getAidlHalInstanceNames ফাংশন সহ সিস্টেমে ইনস্টল করা প্রতিটি HAL এর একটি তালিকা পেতে পারেন। Rust এ, binder::get_declared_instances ব্যবহার করুন।

এই পরীক্ষাগুলি HAL বাস্তবায়নের প্রতিটি দিক কভার করার চেষ্টা করে যার উপর অ্যান্ড্রয়েড ফ্রেমওয়ার্ক নির্ভর করে, অথবা ভবিষ্যতে নির্ভর করতে পারে।

এই পরীক্ষাগুলির মধ্যে রয়েছে বৈশিষ্ট্যগুলির সমর্থন যাচাই করা, ত্রুটি পরিচালনা করা এবং পরিষেবা থেকে ক্লায়েন্টের প্রত্যাশা করা অন্য কোনও আচরণ।

HAL উন্নয়নের জন্য VTS মাইলফলক

অ্যান্ড্রয়েডের HAL ইন্টারফেস তৈরি বা পরিবর্তন করার সময় VTS পরীক্ষা (অথবা যেকোনো পরীক্ষা) হালনাগাদ রাখা হবে বলে আশা করা হচ্ছে।

অ্যান্ড্রয়েড ভেন্ডর এপিআই রিলিজের জন্য ফ্রিজ করার আগে ভিটিএস পরীক্ষাগুলি অবশ্যই সম্পন্ন এবং ভেন্ডর বাস্তবায়ন যাচাই করার জন্য প্রস্তুত থাকতে হবে। ইন্টারফেসগুলি ফ্রিজ করার আগে এগুলি অবশ্যই প্রস্তুত থাকতে হবে যাতে ডেভেলপাররা তাদের বাস্তবায়ন তৈরি করতে, যাচাই করতে এবং এইচএএল ইন্টারফেস ডেভেলপারদের প্রতিক্রিয়া জানাতে পারে।

কাটলফিশের উপর পরীক্ষা

যখন হার্ডওয়্যার উপলব্ধ থাকে না, তখন অ্যান্ড্রয়েড HAL ইন্টারফেসের জন্য ডেভেলপমেন্ট বাহন হিসেবে Cuttlefish ব্যবহার করে। এটি অ্যান্ড্রয়েডের স্কেলেবল ইন্টিগ্রেশন পরীক্ষার সুযোগ করে দেয়।

hal_implementation_test পরীক্ষা করে যে Cuttlefish-এর কাছে সর্বশেষ HAL ইন্টারফেস সংস্করণের বাস্তবায়ন আছে কিনা তা নিশ্চিত করার জন্য যে অ্যান্ড্রয়েড নতুন ইন্টারফেসগুলি পরিচালনা করার জন্য প্রস্তুত এবং VTS পরীক্ষাগুলি নতুন হার্ডওয়্যার এবং ডিভাইসগুলি উপলব্ধ হওয়ার সাথে সাথে নতুন বিক্রেতা বাস্তবায়নগুলি পরীক্ষা করার জন্য প্রস্তুত।