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

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

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

প্রেরণা

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

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

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

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

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

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

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

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

উল্লেখ্য যে নীচের কোড উদাহরণে backends ব্যবহার সঠিক, কারণ তিনটি ব্যাকএন্ড রয়েছে (জাভা, এনডিকে এবং সিপিপি)। নিচের কোডটি বলে যে কিভাবে বিশেষভাবে CPP ব্যাকএন্ড নির্বাচন করতে হয়, এটি নিষ্ক্রিয় করতে।

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

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

HAL-এর জন্য AOSP স্থিতিশীল AIDL ইন্টারফেসগুলি HIDL ইন্টারফেসের মতো একই বেস ডিরেক্টরিতে, aidl ফোল্ডারে রয়েছে।

  • হার্ডওয়্যার/ইন্টারফেস
  • ফ্রেমওয়ার্ক/হার্ডওয়্যার/ইন্টারফেস
  • সিস্টেম/হার্ডওয়্যার/ইন্টারফেস

আপনার উচিত vendor বা hardware অন্যান্য hardware/interfaces সাবডিরেক্টরিতে এক্সটেনশন ইন্টারফেস রাখা।

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

অ্যান্ড্রয়েডের প্রতিটি রিলিজের সাথে অফিসিয়াল AOSP ইন্টারফেসের একটি সেট রয়েছে। যখন অ্যান্ড্রয়েড অংশীদাররা এই ইন্টারফেসে কার্যকারিতা যোগ করতে চায়, তখন তাদের সরাসরি এগুলি পরিবর্তন করা উচিত নয় কারণ এর অর্থ তাদের Android রানটাইম AOSP Android রানটাইমের সাথে সামঞ্জস্যপূর্ণ নয়৷ জিএমএস ডিভাইসগুলির জন্য, এই ইন্টারফেসগুলি পরিবর্তন করা এড়ানোও জিএসআই চিত্রটি কাজ চালিয়ে যেতে পারে তা নিশ্চিত করে।

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

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

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

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

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

পূর্বে ParcelableHolder ছাড়া, ডিভাইস বাস্তবায়নকারীরা একটি AOSP-সংজ্ঞায়িত স্থিতিশীল AIDL ইন্টারফেস সংশোধন করতে পারেনি কারণ এটি আরও ক্ষেত্র যোগ করা একটি ত্রুটি হবে:

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

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

ParcelableHolder ব্যবহার করে, একটি পার্সেবলের মালিক একটি 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 এর তিনটি ভিন্ন ব্যাকএন্ড রয়েছে: Java, NDK, CPP। Stable AIDL ব্যবহার করার জন্য, আপনাকে সর্বদা system/lib*/libbinder.so এ libbinder-এর সিস্টেম কপি ব্যবহার করতে হবে এবং /dev/binder এ কথা বলতে হবে। বিক্রেতা চিত্রের কোডের জন্য, এর অর্থ হল libbinder (ভিএনডিকে থেকে) ব্যবহার করা যাবে না: এই লাইব্রেরিতে একটি অস্থির C++ API এবং অস্থির অভ্যন্তরীণ রয়েছে। পরিবর্তে, নেটিভ ভেন্ডর কোড অবশ্যই AIDL-এর NDK ব্যাকএন্ড ব্যবহার করতে হবে, libbinder_ndk বিরুদ্ধে লিঙ্ক (যা সিস্টেম libbinder.so দ্বারা সমর্থিত), এবং aidl_interface এন্ট্রি দ্বারা তৈরি -ndk_platform লাইব্রেরির বিরুদ্ধে লিঙ্ক।

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 ক্লায়েন্ট লেখা

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

    <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 ফাইলের উপর ভিত্তি করে .aidl ফাইল তৈরি করুন
  • সমস্ত ব্যাকএন্ড সক্ষম করে নতুন তৈরি AIDL প্যাকেজের জন্য বিল্ড নিয়ম তৈরি করুন
  • HIDL প্রকার থেকে AIDL প্রকারে অনুবাদ করার জন্য Java, CPP, এবং NDK ব্যাকএন্ডে অনুবাদ পদ্ধতি তৈরি করুন
  • প্রয়োজনীয় নির্ভরতা সহ লাইব্রেরি অনুবাদের জন্য বিল্ড নিয়ম তৈরি করুন
  • এইচআইডিএল এবং এআইডিএল গণনাকারীদের সিপিপি এবং এনডিকে ব্যাকএন্ডে একই মান রয়েছে তা নিশ্চিত করতে স্ট্যাটিক অ্যাসার্ট তৈরি করুন

.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 ব্যাকএন্ড পছন্দ করুন, রানটাইম নির্বাচন করা দেখুন।
    • ট্রান্সলেট লাইব্রেরি বা তাদের জেনারেট করা কোনো কোড সরান যা ব্যবহার করা হবে না।
  5. প্রধান AIDL/HIDL পার্থক্য দেখুন।

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

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

একটি AIDL পরিষেবার ধরন যা বিক্রেতা কোডে দৃশ্যমান তার অবশ্যই hal_service_type বৈশিষ্ট্য থাকতে হবে। অন্যথায়, সেপলিসি কনফিগারেশন অন্য যেকোন 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, 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_foo_default এর মতো একটি ডোমেনও তৈরি করি। যাইহোক, কিছু ডিভাইস তাদের নিজস্ব সার্ভারের জন্য এই ডোমেনগুলি ব্যবহার করে। একাধিক সার্ভারের জন্য ডোমেনের মধ্যে পার্থক্য করা কেবল তখনই গুরুত্বপূর্ণ যদি আমাদের একাধিক সার্ভার থাকে যা একই ইন্টারফেস পরিবেশন করে এবং তাদের বাস্তবায়নে আলাদা অনুমতির প্রয়োজন হয়। এই সমস্ত ম্যাক্রোতে, hal_foo আসলে একটি সেপলিসি অবজেক্ট নয়। পরিবর্তে, এই টোকেনটি এই ম্যাক্রো দ্বারা ব্যবহার করা হয় একটি ক্লায়েন্ট সার্ভার পেয়ারের সাথে যুক্ত অ্যাট্রিবিউটের গ্রুপকে উল্লেখ করতে।

যাইহোক, এখন পর্যন্ত, আমরা hal_foo_service এবং hal_foo ( hal_attribute(foo) থেকে অ্যাট্রিবিউট জোড়া) যুক্ত করিনি। hal_attribute_service ম্যাক্রো (HIDL HALs hal_attribute_hwservice ম্যাক্রো ব্যবহার করে) ব্যবহার করে একটি HAL অ্যাট্রিবিউট AIDL HAL পরিষেবার সাথে যুক্ত। উদাহরণস্বরূপ, 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
  • CPP ব্যাকএন্ডে: android::Binder::setExtension
  • মরিচা ব্যাকএন্ডে: binder::Binder::set_extension

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

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

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

প্রধান AIDL/HIDL পার্থক্য

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

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