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 রানটাইমের সাথে সামঞ্জস্যপূর্ণ নয়৷ জিএমএস ডিভাইসগুলির জন্য, এই ইন্টারফেসগুলি পরিবর্তন করা এড়ানোও জিএসআই চিত্রটি কাজ চালিয়ে যেতে পারে তা নিশ্চিত করে।
এক্সটেনশন দুটি ভিন্ন উপায়ে নিবন্ধন করতে পারে:
- রানটাইমে, সংযুক্ত এক্সটেনশন দেখুন।
- স্বতন্ত্র, বিশ্বব্যাপী এবং VINTF-এ নিবন্ধিত।
তবে একটি এক্সটেনশন নিবন্ধিত হয়, যখন বিক্রেতা-নির্দিষ্ট (অর্থাৎ আপস্ট্রিম 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.so-এ libbinder-এর সিস্টেম কপি ব্যবহার করতে হবে এবং /dev/binder
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 ফাইলে রূপান্তর করতে এই পদক্ষেপগুলি অনুসরণ করুন:
system/tools/hidl/hidl2aidl
এ অবস্থিত টুলটি তৈরি করুন।সর্বশেষ উৎস থেকে এই টুল তৈরি করা সবচেয়ে সম্পূর্ণ অভিজ্ঞতা প্রদান করে। আপনি পূর্ববর্তী রিলিজগুলি থেকে পুরানো শাখাগুলিতে ইন্টারফেস রূপান্তর করতে সর্বশেষ সংস্করণ ব্যবহার করতে পারেন।
m hidl2aidl
রূপান্তরিত করার জন্য প্যাকেজ অনুসরণ করে একটি আউটপুট ডিরেক্টরি সহ টুলটি চালান।
ঐচ্ছিকভাবে, সমস্ত উত্পন্ন ফাইলের শীর্ষে একটি নতুন লাইসেন্স ফাইলের বিষয়বস্তু যোগ করতে
-l
আর্গুমেন্ট ব্যবহার করুন। সঠিক লাইসেন্স এবং তারিখ ব্যবহার করতে ভুলবেন না।hidl2aidl -o <output directory> -l <file with license> <package>
উদাহরণ স্বরূপ:
hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
জেনারেট করা ফাইলগুলি পড়ুন এবং রূপান্তরের সাথে যেকোনো সমস্যা সমাধান করুন।
-
conversion.log
এ কোনো অ-হ্যান্ডেল করা সমস্যা আছে যা প্রথমে ঠিক করতে হবে। - জেনারেট করা
.aidl
ফাইলগুলিতে সতর্কতা এবং পরামর্শ থাকতে পারে যার জন্য পদক্ষেপের প্রয়োজন হতে পারে৷ এই মন্তব্যগুলি//
দিয়ে শুরু হয়। - পরিষ্কার করার এবং প্যাকেজে উন্নতি করার সুযোগ নিন।
- প্রয়োজন হতে পারে এমন বৈশিষ্ট্যগুলির জন্য
@JavaDerive
টীকা পরীক্ষা করুন, যেমনtoString
বাequals
।
-
আপনার প্রয়োজনীয় লক্ষ্যমাত্রা তৈরি করুন।
- ব্যাকএন্ডগুলি অক্ষম করুন যা ব্যবহার করা হবে না। CPP ব্যাকএন্ডের তুলনায় NDK ব্যাকএন্ড পছন্দ করুন, রানটাইম নির্বাচন করা দেখুন।
- ট্রান্সলেট লাইব্রেরি বা তাদের জেনারেট করা কোনো কোড সরান যা ব্যবহার করা হবে না।
প্রধান AIDL/HIDL পার্থক্য দেখুন।
- AIDL-এর অন্তর্নির্মিত
Status
এবং ব্যতিক্রমগুলি ব্যবহার করে সাধারণত ইন্টারফেসকে উন্নত করে এবং অন্য ইন্টারফেস-নির্দিষ্ট স্থিতি প্রকারের প্রয়োজনীয়তা দূর করে। - পদ্ধতিতে AIDL ইন্টারফেস আর্গুমেন্ট ডিফল্টরূপে @
@nullable
নয় যেমন তারা HIDL-এ ছিল।
- AIDL-এর অন্তর্নির্মিত
এআইডিএল এইচএএল-এর জন্য সেপলিসি
একটি 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_foo_service
অপসারণ এবং hal_foo2_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
একটি বাইন্ডারে একটি এক্সটেনশন পেতে, নিম্নলিখিত API ব্যবহার করুন:
- NDK ব্যাকএন্ডে:
AIBinder_getExtension
- জাভা ব্যাকএন্ডে:
android.os.IBinder.getExtension
- CPP ব্যাকএন্ডে:
android::IBinder::getExtension
আপনি সংশ্লিষ্ট ব্যাকএন্ডে getExtension
ফাংশনের ডকুমেন্টেশনে এই APIগুলির জন্য আরও তথ্য পেতে পারেন। কিভাবে এক্সটেনশন ব্যবহার করতে হয় তার একটি উদাহরণ হার্ডওয়্যার/ইন্টারফেস/টেস্ট/এক্সটেনশন/ভাইব্রেটরে পাওয়া যাবে।
প্রধান AIDL/HIDL পার্থক্য
AIDL HALs ব্যবহার করার সময় বা AIDL HAL ইন্টারফেস ব্যবহার করার সময়, HIDL HAL লেখার তুলনায় পার্থক্য সম্পর্কে সচেতন হন।
- AIDL ভাষার সিনট্যাক্স জাভার কাছাকাছি। HIDL সিনট্যাক্স C++ এর মত।
- সমস্ত AIDL ইন্টারফেসে অন্তর্নির্মিত ত্রুটি অবস্থা রয়েছে। কাস্টম স্ট্যাটাস টাইপ তৈরি করার পরিবর্তে, ইন্টারফেস ফাইলগুলিতে স্থির স্ট্যাটাস ইনট তৈরি করুন এবং CPP/NDK ব্যাকএন্ডে
ServiceSpecificException
এবং Java ব্যাকএন্ডেEX_SERVICE_SPECIFIC
ব্যবহার করুন। এরর হ্যান্ডলিং দেখুন। - বাইন্ডার বস্তু পাঠানো হলে AIDL স্বয়ংক্রিয়ভাবে থ্রেডপুল শুরু করে না। সেগুলি ম্যানুয়ালি শুরু করতে হবে ( থ্রেড ব্যবস্থাপনা দেখুন)।
- AIDL আনচেক করা পরিবহন ত্রুটির উপর গর্ভপাত করে না (HIDL
Return
অ্যাবর্টস অন চেকড এররস)। - এআইডিএল প্রতি ফাইলে শুধুমাত্র একটি প্রকার ঘোষণা করতে পারে।
- এআইডিএল আর্গুমেন্টগুলি আউটপুট প্যারামিটার ছাড়াও ইন/আউট/ইনআউট হিসাবে নির্দিষ্ট করা যেতে পারে (কোন "সিঙ্ক্রোনাস কলব্যাক" নেই)।
- এআইডিএল হ্যান্ডেলের পরিবর্তে আদিম প্রকার হিসাবে fd ব্যবহার করে।
- HIDL অসামঞ্জস্যপূর্ণ পরিবর্তনের জন্য প্রধান সংস্করণ এবং সামঞ্জস্যপূর্ণ পরিবর্তনের জন্য ছোট সংস্করণ ব্যবহার করে। এআইডিএল-এ, পিছনের-সামঞ্জস্যপূর্ণ পরিবর্তনগুলি জায়গায় করা হয়। এআইডিএল-এর প্রধান সংস্করণগুলির কোনও স্পষ্ট ধারণা নেই; পরিবর্তে, এটি প্যাকেজ নামের মধ্যে অন্তর্ভুক্ত করা হয়। উদাহরণস্বরূপ, AIDL প্যাকেজ নাম
bluetooth2
ব্যবহার করতে পারে। - এআইডিএল ডিফল্টরূপে রিয়েলটাইম অগ্রাধিকারের উত্তরাধিকারী হয় না। রিয়েলটাইম অগ্রাধিকার উত্তরাধিকার সক্ষম করতে
setInheritRt
ফাংশন প্রতি-বাইন্ডার ব্যবহার করা আবশ্যক।
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 রানটাইমের সাথে সামঞ্জস্যপূর্ণ নয়৷ জিএমএস ডিভাইসগুলির জন্য, এই ইন্টারফেসগুলি পরিবর্তন করা এড়ানোও জিএসআই চিত্রটি কাজ চালিয়ে যেতে পারে তা নিশ্চিত করে।
এক্সটেনশন দুটি ভিন্ন উপায়ে নিবন্ধন করতে পারে:
- রানটাইমে, সংযুক্ত এক্সটেনশন দেখুন।
- স্বতন্ত্র, বিশ্বব্যাপী এবং VINTF-এ নিবন্ধিত।
তবে একটি এক্সটেনশন নিবন্ধিত হয়, যখন বিক্রেতা-নির্দিষ্ট (অর্থাৎ আপস্ট্রিম 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.so-এ libbinder-এর সিস্টেম কপি ব্যবহার করতে হবে এবং /dev/binder
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 ফাইলে রূপান্তর করতে এই পদক্ষেপগুলি অনুসরণ করুন:
system/tools/hidl/hidl2aidl
এ অবস্থিত টুলটি তৈরি করুন।সর্বশেষ উৎস থেকে এই টুল তৈরি করা সবচেয়ে সম্পূর্ণ অভিজ্ঞতা প্রদান করে। আপনি পূর্ববর্তী রিলিজগুলি থেকে পুরানো শাখাগুলিতে ইন্টারফেস রূপান্তর করতে সর্বশেষ সংস্করণ ব্যবহার করতে পারেন।
m hidl2aidl
রূপান্তরিত করার জন্য প্যাকেজ অনুসরণ করে একটি আউটপুট ডিরেক্টরি সহ টুলটি চালান।
ঐচ্ছিকভাবে, সমস্ত উত্পন্ন ফাইলের শীর্ষে একটি নতুন লাইসেন্স ফাইলের বিষয়বস্তু যোগ করতে
-l
আর্গুমেন্ট ব্যবহার করুন। সঠিক লাইসেন্স এবং তারিখ ব্যবহার করতে ভুলবেন না।hidl2aidl -o <output directory> -l <file with license> <package>
উদাহরণ স্বরূপ:
hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
জেনারেট করা ফাইলগুলি পড়ুন এবং রূপান্তরের সাথে যেকোনো সমস্যা সমাধান করুন।
-
conversion.log
এ কোনো অ-হ্যান্ডেল করা সমস্যা আছে যা প্রথমে ঠিক করতে হবে। - জেনারেট করা
.aidl
ফাইলগুলিতে সতর্কতা এবং পরামর্শ থাকতে পারে যার জন্য পদক্ষেপের প্রয়োজন হতে পারে৷ এই মন্তব্যগুলি//
দিয়ে শুরু হয়। - পরিষ্কার করার এবং প্যাকেজে উন্নতি করার সুযোগ নিন।
- প্রয়োজন হতে পারে এমন বৈশিষ্ট্যগুলির জন্য
@JavaDerive
টীকা পরীক্ষা করুন, যেমনtoString
বাequals
।
-
আপনার প্রয়োজনীয় লক্ষ্যমাত্রা তৈরি করুন।
- ব্যাকএন্ডগুলি অক্ষম করুন যা ব্যবহার করা হবে না। CPP ব্যাকএন্ডের তুলনায় NDK ব্যাকএন্ড পছন্দ করুন, রানটাইম নির্বাচন করা দেখুন।
- ট্রান্সলেট লাইব্রেরি বা তাদের জেনারেট করা কোনো কোড সরান যা ব্যবহার করা হবে না।
প্রধান AIDL/HIDL পার্থক্য দেখুন।
- AIDL-এর অন্তর্নির্মিত
Status
এবং ব্যতিক্রমগুলি ব্যবহার করে সাধারণত ইন্টারফেসকে উন্নত করে এবং অন্য ইন্টারফেস-নির্দিষ্ট স্থিতি প্রকারের প্রয়োজনীয়তা দূর করে। - পদ্ধতিতে AIDL ইন্টারফেস আর্গুমেন্ট ডিফল্টরূপে @
@nullable
নয় যেমন তারা HIDL-এ ছিল।
- AIDL-এর অন্তর্নির্মিত
এআইডিএল এইচএএল-এর জন্য সেপলিসি
একটি 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_foo_service
অপসারণ এবং hal_foo2_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
একটি বাইন্ডারে একটি এক্সটেনশন পেতে, নিম্নলিখিত API ব্যবহার করুন:
- NDK ব্যাকএন্ডে:
AIBinder_getExtension
- জাভা ব্যাকএন্ডে:
android.os.IBinder.getExtension
- CPP ব্যাকএন্ডে:
android::IBinder::getExtension
আপনি সংশ্লিষ্ট ব্যাকএন্ডে getExtension
ফাংশনের ডকুমেন্টেশনে এই APIগুলির জন্য আরও তথ্য পেতে পারেন। কিভাবে এক্সটেনশন ব্যবহার করতে হয় তার একটি উদাহরণ হার্ডওয়্যার/ইন্টারফেস/টেস্ট/এক্সটেনশন/ভাইব্রেটরে পাওয়া যাবে।
প্রধান AIDL/HIDL পার্থক্য
AIDL HALs ব্যবহার করার সময় বা AIDL HAL ইন্টারফেস ব্যবহার করার সময়, HIDL HAL লেখার তুলনায় পার্থক্য সম্পর্কে সচেতন হন।
- AIDL ভাষার সিনট্যাক্স জাভার কাছাকাছি। HIDL সিনট্যাক্স C++ এর মত।
- সমস্ত AIDL ইন্টারফেসে অন্তর্নির্মিত ত্রুটি অবস্থা রয়েছে। কাস্টম স্ট্যাটাস টাইপ তৈরি করার পরিবর্তে, ইন্টারফেস ফাইলগুলিতে স্থির স্ট্যাটাস ইনট তৈরি করুন এবং CPP/NDK ব্যাকএন্ডে
ServiceSpecificException
এবং Java ব্যাকএন্ডেEX_SERVICE_SPECIFIC
ব্যবহার করুন। এরর হ্যান্ডলিং দেখুন। - বাইন্ডার বস্তু পাঠানো হলে AIDL স্বয়ংক্রিয়ভাবে থ্রেডপুল শুরু করে না। সেগুলি ম্যানুয়ালি শুরু করতে হবে ( থ্রেড ব্যবস্থাপনা দেখুন)।
- AIDL আনচেক করা পরিবহন ত্রুটির উপর গর্ভপাত করে না (HIDL
Return
অ্যাবর্টস অন চেকড এররস)। - এআইডিএল প্রতি ফাইলে শুধুমাত্র একটি প্রকার ঘোষণা করতে পারে।
- এআইডিএল আর্গুমেন্টগুলি আউটপুট প্যারামিটার ছাড়াও ইন/আউট/ইনআউট হিসাবে নির্দিষ্ট করা যেতে পারে (কোন "সিঙ্ক্রোনাস কলব্যাক" নেই)।
- এআইডিএল হ্যান্ডেলের পরিবর্তে আদিম প্রকার হিসাবে fd ব্যবহার করে।
- HIDL অসামঞ্জস্যপূর্ণ পরিবর্তনের জন্য প্রধান সংস্করণ এবং সামঞ্জস্যপূর্ণ পরিবর্তনের জন্য ছোট সংস্করণ ব্যবহার করে। এআইডিএল-এ, পিছনের-সামঞ্জস্যপূর্ণ পরিবর্তনগুলি জায়গায় করা হয়। এআইডিএল-এর প্রধান সংস্করণগুলির কোনও স্পষ্ট ধারণা নেই; পরিবর্তে, এটি প্যাকেজ নামের মধ্যে অন্তর্ভুক্ত করা হয়। উদাহরণস্বরূপ, AIDL প্যাকেজ নাম
bluetooth2
ব্যবহার করতে পারে। - এআইডিএল ডিফল্টরূপে রিয়েলটাইম অগ্রাধিকারের উত্তরাধিকারী হয় না। রিয়েলটাইম অগ্রাধিকার উত্তরাধিকার সক্ষম করতে
setInheritRt
ফাংশন প্রতি-বাইন্ডার ব্যবহার করা আবশ্যক।