HIDL-এর জন্য HIDL-এ লেখা প্রতিটি ইন্টারফেস সংস্করণ করা প্রয়োজন। একটি HAL ইন্টারফেস প্রকাশিত হওয়ার পরে, এটি হিমায়িত করা হয় এবং সেই ইন্টারফেসের একটি নতুন সংস্করণে আরও কোনো পরিবর্তন করতে হবে। একটি প্রদত্ত প্রকাশিত ইন্টারফেস পরিবর্তন করা যাবে না, এটি অন্য ইন্টারফেস দ্বারা প্রসারিত করা যেতে পারে.
HIDL কোড গঠন
HIDL কোড ব্যবহারকারী-সংজ্ঞায়িত প্রকার, ইন্টারফেস এবং প্যাকেজে সংগঠিত :
- ব্যবহারকারী-সংজ্ঞায়িত প্রকার (UDTs) । HIDL আদিম ডেটা প্রকারের একটি সেটে অ্যাক্সেস সরবরাহ করে যা কাঠামো, ইউনিয়ন এবং গণনার মাধ্যমে আরও জটিল প্রকার রচনা করতে ব্যবহার করা যেতে পারে। ইউডিটিগুলি ইন্টারফেসের পদ্ধতিতে প্রেরণ করা হয় এবং একটি প্যাকেজের স্তরে (সকল ইন্টারফেসে সাধারণ) বা স্থানীয়ভাবে একটি ইন্টারফেসে সংজ্ঞায়িত করা যেতে পারে।
- ইন্টারফেস HIDL এর একটি মৌলিক বিল্ডিং ব্লক হিসাবে, একটি ইন্টারফেস UDT এবং পদ্ধতি ঘোষণা নিয়ে গঠিত। ইন্টারফেসগুলি অন্য ইন্টারফেস থেকেও উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে।
- প্যাকেজ সম্পর্কিত HIDL ইন্টারফেস এবং তারা কাজ করে এমন ডেটা প্রকারগুলিকে সংগঠিত করে৷ একটি প্যাকেজ একটি নাম এবং একটি সংস্করণ দ্বারা চিহ্নিত করা হয় এবং নিম্নলিখিতগুলি অন্তর্ভুক্ত করে:
- ডেটা-টাইপ ডেফিনিশন ফাইলটিকে
types.hal
বলা হয়। - শূন্য বা তার বেশি ইন্টারফেস, প্রতিটি তাদের নিজস্ব
.hal
ফাইলে।
- ডেটা-টাইপ ডেফিনিশন ফাইলটিকে
ডেটা-টাইপ সংজ্ঞা ফাইল types.hal
এ শুধুমাত্র UDTs রয়েছে (সমস্ত প্যাকেজ-স্তরের UDTs একটি একক ফাইলে রাখা হয়)। টার্গেট ভাষায় উপস্থাপনা প্যাকেজের সমস্ত ইন্টারফেসে উপলব্ধ।
সংস্করণ দর্শন
একটি HIDL প্যাকেজ (যেমন android.hardware.nfc
), প্রদত্ত সংস্করণের জন্য প্রকাশিত হওয়ার পরে (যেমন 1.0
), অপরিবর্তনীয়; এটা পরিবর্তন করা যাবে না. প্যাকেজের ইন্টারফেসে পরিবর্তন বা এর UDT-তে কোনো পরিবর্তন শুধুমাত্র অন্য প্যাকেজেই ঘটতে পারে।
HIDL-এ, সংস্করণিং প্যাকেজ স্তরে প্রযোজ্য, ইন্টারফেস স্তরে নয়, এবং প্যাকেজের সমস্ত ইন্টারফেস এবং UDT একই সংস্করণ ভাগ করে। প্যাকেজ সংস্করণ প্যাচ স্তর এবং বিল্ড-মেটাডেটা উপাদান ছাড়া শব্দার্থিক সংস্করণ অনুসরণ করে। একটি প্রদত্ত প্যাকেজের মধ্যে, একটি ছোট সংস্করণ বাম্প বোঝায় প্যাকেজের নতুন সংস্করণটি পুরানো প্যাকেজের সাথে পিছনের-সামঞ্জস্যপূর্ণ এবং একটি বড় সংস্করণের বাম্প বোঝায় প্যাকেজের নতুন সংস্করণটি পুরানো প্যাকেজের সাথে সামঞ্জস্যপূর্ণ নয়৷
ধারণাগতভাবে, একটি প্যাকেজ বিভিন্ন উপায়ে অন্য একটি প্যাকেজের সাথে সম্পর্কিত হতে পারে:
- মোটেও না ।
- প্যাকেজ-স্তরের পিছনের-সামঞ্জস্যপূর্ণ এক্সটেনসিবিলিটি । এটি একটি প্যাকেজের নতুন ছোট-সংস্করণ uprevs (পরবর্তী বর্ধিত সংশোধন) জন্য ঘটে; নতুন প্যাকেজের পুরোনো প্যাকেজের মতো একই নাম এবং প্রধান সংস্করণ রয়েছে, তবে একটি উচ্চতর ছোট সংস্করণ। কার্যকরীভাবে, নতুন প্যাকেজটি পুরানো প্যাকেজের একটি সুপারসেট, যার অর্থ:
- মূল প্যাকেজের শীর্ষ-স্তরের ইন্টারফেসগুলি নতুন প্যাকেজে উপস্থিত রয়েছে, যদিও ইন্টারফেসগুলিতে নতুন পদ্ধতি, নতুন ইন্টারফেস-স্থানীয় UDTs (নিচে বর্ণিত ইন্টারফেস-স্তরের এক্সটেনশন), এবং
types.hal
এ নতুন UDTs থাকতে পারে। - নতুন প্যাকেজে নতুন ইন্টারফেসও যোগ করা যেতে পারে।
- প্যারেন্ট প্যাকেজের সমস্ত ডেটা প্রকার নতুন প্যাকেজে উপস্থিত রয়েছে এবং পুরানো প্যাকেজ থেকে (সম্ভবত পুনরায় প্রয়োগ করা) পদ্ধতি দ্বারা পরিচালনা করা যেতে পারে।
- নতুন ডাটা টাইপগুলিও ব্যবহার করার জন্য যুক্ত করা যেতে পারে আপপ্রেভ'ড বিদ্যমান ইন্টারফেসের নতুন পদ্ধতি বা নতুন ইন্টারফেসের মাধ্যমে।
- মূল প্যাকেজের শীর্ষ-স্তরের ইন্টারফেসগুলি নতুন প্যাকেজে উপস্থিত রয়েছে, যদিও ইন্টারফেসগুলিতে নতুন পদ্ধতি, নতুন ইন্টারফেস-স্থানীয় UDTs (নিচে বর্ণিত ইন্টারফেস-স্তরের এক্সটেনশন), এবং
- ইন্টারফেস-স্তরের পিছনের-সামঞ্জস্যপূর্ণ এক্সটেনসিবিলিটি । নতুন প্যাকেজটি যৌক্তিকভাবে পৃথক ইন্টারফেসগুলির সমন্বয়ে মূল প্যাকেজটিকেও প্রসারিত করতে পারে যা কেবলমাত্র অতিরিক্ত কার্যকারিতা প্রদান করে, মূলটি নয়। এই উদ্দেশ্যে, নিম্নলিখিতগুলি কাম্য হতে পারে:
- নতুন প্যাকেজের ইন্টারফেসগুলিকে পুরানো প্যাকেজের ডেটা প্রকারের আশ্রয় নিতে হবে।
- নতুন প্যাকেজের ইন্টারফেসগুলি এক বা একাধিক পুরানো প্যাকেজের ইন্টারফেস প্রসারিত করতে পারে।
- মূলটি পিছনের দিকে প্রসারিত করুন - অসঙ্গতি । এটি প্যাকেজের একটি প্রধান-সংস্করণ আপপ্রেভ এবং উভয়ের মধ্যে কোনো সম্পর্ক থাকার প্রয়োজন নেই। যে পরিমাণে আছে, এটি প্যাকেজের পুরানো সংস্করণ থেকে এবং পুরানো-প্যাকেজ ইন্টারফেসের একটি উপসেটের উত্তরাধিকারের সংমিশ্রণে প্রকাশ করা যেতে পারে।
ইন্টারফেস গঠন
একটি সুগঠিত ইন্টারফেসের জন্য, মূল ডিজাইনের অংশ নয় এমন নতুন ধরনের কার্যকারিতা যোগ করার জন্য HIDL ইন্টারফেসে পরিবর্তনের প্রয়োজন। বিপরীতভাবে, যদি আপনি ইন্টারফেসের উভয় দিকে পরিবর্তন করতে পারেন বা আশা করতে পারেন যা ইন্টারফেসটি পরিবর্তন না করেই নতুন কার্যকারিতা প্রবর্তন করে, তাহলে ইন্টারফেসটি কাঠামোগত নয়।
Treble আলাদাভাবে কম্পাইল করা ভেন্ডর এবং সিস্টেম কম্পোনেন্ট সমর্থন করে যেখানে একটি ডিভাইসে vendor.img
এবং system.img
আলাদাভাবে কম্পাইল করা যায়। vendor.img
এবং system.img
মধ্যে সমস্ত মিথস্ক্রিয়া অবশ্যই স্পষ্টভাবে এবং পুঙ্খানুপুঙ্খভাবে সংজ্ঞায়িত করা উচিত যাতে তারা বহু বছর ধরে কাজ চালিয়ে যেতে পারে। এর মধ্যে অনেকগুলি API সারফেস রয়েছে, কিন্তু একটি প্রধান সারফেস হল IPC মেকানিজম HIDL system.img
/ vendor.img
সীমানায় আন্তঃপ্রক্রিয়া যোগাযোগের জন্য ব্যবহার করে।
প্রয়োজনীয়তা
HIDL এর মাধ্যমে পাস করা সমস্ত ডেটা অবশ্যই স্পষ্টভাবে সংজ্ঞায়িত করা উচিত। একটি বাস্তবায়ন নিশ্চিত করতে এবং ক্লায়েন্ট আলাদাভাবে কম্পাইল করা বা স্বাধীনভাবে বিকশিত হওয়া সত্ত্বেও একসাথে কাজ চালিয়ে যেতে পারে, ডেটা নিম্নলিখিত প্রয়োজনীয়তাগুলি মেনে চলতে হবে:
- HIDL-এ সরাসরি (structs enums, ইত্যাদি ব্যবহার করে) শব্দার্থগত নাম এবং অর্থ সহ বর্ণনা করা যেতে পারে।
- ISO/IEC 7816 এর মতো একটি পাবলিক স্ট্যান্ডার্ড দ্বারা বর্ণনা করা যেতে পারে।
- হার্ডওয়্যার স্ট্যান্ডার্ড বা হার্ডওয়্যারের ফিজিক্যাল লেআউট দ্বারা বর্ণনা করা যেতে পারে।
- প্রয়োজনে অস্বচ্ছ ডেটা (যেমন পাবলিক কী, আইডি ইত্যাদি) হতে পারে।
অস্বচ্ছ ডেটা ব্যবহার করা হলে, এটি শুধুমাত্র HIDL ইন্টারফেসের একপাশে পড়তে হবে। উদাহরণস্বরূপ, যদি vendor.img
কোড system.img
এ একটি কম্পোনেন্ট দেয় একটি স্ট্রিং বার্তা বা vec<uint8_t>
ডেটা, সেই ডেটা system.img
দ্বারা পার্স করা যাবে না; ব্যাখ্যা করার জন্য এটি শুধুমাত্র vendor.img
এ ফেরত পাঠানো যেতে পারে। system.img
এ vendor.img
থেকে ভেন্ডর কোডে বা অন্য ডিভাইসে একটি মান পাস করার সময়, ডেটার বিন্যাস এবং কীভাবে এটি ব্যাখ্যা করা হবে তা অবশ্যই সঠিকভাবে বর্ণনা করতে হবে এবং এখনও ইন্টারফেসের অংশ।
নির্দেশিকা
আপনি শুধুমাত্র .hal ফাইল ব্যবহার করে একটি HAL এর বাস্তবায়ন বা ক্লায়েন্ট লিখতে সক্ষম হবেন (অর্থাৎ আপনার Android উত্স বা পাবলিক স্ট্যান্ডার্ডগুলি দেখার দরকার নেই)৷ আমরা সঠিক প্রয়োজনীয় আচরণ নির্দিষ্ট করার সুপারিশ করি। বিবৃতি যেমন "একটি বাস্তবায়ন A বা B করতে পারে" বাস্তবায়নকে উৎসাহিত করে যে ক্লায়েন্টদের সাথে তারা তৈরি হয়েছে তাদের সাথে জড়িত হতে।
HIDL কোড লেআউট
HIDL এর মূল এবং বিক্রেতা প্যাকেজ অন্তর্ভুক্ত।
কোর HIDL ইন্টারফেসগুলি Google দ্বারা নির্দিষ্ট করা হয়৷ যে প্যাকেজগুলি তারা android.hardware.
এবং সাবসিস্টেম দ্বারা নামকরণ করা হয়, সম্ভাব্য নেস্টেড স্তরের নামকরণ সহ। উদাহরণস্বরূপ, NFC প্যাকেজটির নাম android.hardware.nfc
এবং ক্যামেরা প্যাকেজটি android.hardware.camera
। সাধারণভাবে, একটি মূল প্যাকেজের নাম android.hardware.
[ name1
] [ name2
]…. HIDL প্যাকেজগুলির নামের পাশাপাশি একটি সংস্করণ রয়েছে৷ উদাহরণস্বরূপ, প্যাকেজ android.hardware.camera
সংস্করণ 3.4
এ হতে পারে; এটি গুরুত্বপূর্ণ, কারণ একটি প্যাকেজের সংস্করণ উত্স ট্রিতে এটির স্থাপনকে প্রভাবিত করে।
সমস্ত মূল প্যাকেজ বিল্ড সিস্টেমে hardware/interfaces/
অধীনে রাখা হয়। প্যাকেজ android.hardware.
[ name1
] [ name2
]… $m.$n
সংস্করণে hardware/interfaces/name1/name2/
… /$m.$n/
; প্যাকেজ android.hardware.camera
সংস্করণ 3.4
hardware/interfaces/camera/3.4/.
প্যাকেজ প্রিফিক্স android.hardware.
এবং পথ hardware/interfaces/
।
নন-কোর (বিক্রেতা) প্যাকেজগুলি হল যেগুলি SoC বিক্রেতা বা ODM দ্বারা উত্পাদিত৷ নন-কোর প্যাকেজের উপসর্গ হল vendor.$(VENDOR).hardware.
যেখানে $(VENDOR)
বলতে একটি SoC বিক্রেতা বা OEM/ODM বোঝায়। এই ম্যাপ ট্রিতে পাথ vendor/$(VENDOR)/interfaces
(এই ম্যাপিংটিও হার্ড কোডেড)।
সম্পূর্ণরূপে যোগ্য ব্যবহারকারী-সংজ্ঞায়িত-টাইপ নাম
HIDL-এ, প্রতিটি UDT-এর একটি সম্পূর্ণ যোগ্য নাম থাকে যা UDT নাম, প্যাকেজের নাম যেখানে UDT সংজ্ঞায়িত করা হয় এবং প্যাকেজ সংস্করণ থাকে। সম্পূর্ণ যোগ্য নামটি শুধুমাত্র তখনই ব্যবহৃত হয় যখন টাইপের উদাহরণ ঘোষণা করা হয় এবং যেখানে টাইপটি নিজেই সংজ্ঞায়িত করা হয় সেখানে নয়। উদাহরণস্বরূপ, অনুমান করুন প্যাকেজ android.hardware.nfc,
সংস্করণ 1.0
NfcData
নামে একটি স্ট্রাকটকে সংজ্ঞায়িত করে। ঘোষণার সাইটে (তাই types.hal
বা ইন্টারফেসের ঘোষণার মধ্যে), ঘোষণাটি সহজভাবে বলে:
struct NfcData { vec<uint8_t> data; };
এই ধরনের একটি দৃষ্টান্ত ঘোষণা করার সময় (ডাটা স্ট্রাকচারের মধ্যেই হোক বা পদ্ধতির প্যারামিটার হিসাবে), সম্পূর্ণ যোগ্য টাইপ নামটি ব্যবহার করুন:
android.hardware.nfc@1.0::NfcData
সাধারণ সিনট্যাক্স হল PACKAGE @ VERSION :: UDT
, যেখানে:
-
PACKAGE
হল একটি HIDL প্যাকেজের ডট-বিভক্ত নাম (যেমন,android.hardware.nfc
)। -
VERSION
হল প্যাকেজের ডট-বিভাজিত major.minor-সংস্করণ বিন্যাস (যেমন,1.0
)। -
UDT
হল একটি HIDL UDT-এর ডট-বিভক্ত নাম। যেহেতু এইচআইডিএল নেস্টেড ইউডিটি সমর্থন করে এবং এইচআইডিএল ইন্টারফেসে ইউডিটি (এক ধরনের নেস্টেড ঘোষণা) থাকতে পারে, তাই নামগুলি অ্যাক্সেস করতে ডট ব্যবহার করা হয়।
উদাহরণস্বরূপ, যদি নিম্নলিখিত নেস্টেড ঘোষণা প্যাকেজ android.hardware.example
সংস্করণ 1.0
-এর সাধারণ প্রকার ফাইলে সংজ্ঞায়িত করা হয়:
// types.hal package android.hardware.example@1.0; struct Foo { struct Bar { // … }; Bar cheers; };
Bar
জন্য সম্পূর্ণ যোগ্য নাম হল android.hardware.example@1.0::Foo.Bar
। যদি, উপরের প্যাকেজে থাকা ছাড়াও, নেস্টেড ঘোষণাটি IQuux
নামক একটি ইন্টারফেসে থাকে:
// IQuux.hal package android.hardware.example@1.0; interface IQuux { struct Foo { struct Bar { // … }; Bar cheers; }; doSomething(Foo f) generates (Foo.Bar fb); };
Bar
জন্য সম্পূর্ণ যোগ্য নাম হল android.hardware.example@1.0::IQuux.Foo.Bar
।
উভয় ক্ষেত্রেই, Bar
Bar
হিসাবে উল্লেখ করা যেতে পারে শুধুমাত্র Foo
ঘোষণার সুযোগের মধ্যে। প্যাকেজ বা ইন্টারফেস স্তরে, আপনাকে অবশ্যই Bar
Foo
: Foo.Bar
এর মাধ্যমে উল্লেখ করতে হবে, যেমন উপরে doSomething
পদ্ধতি ঘোষণা করা হয়েছে। বিকল্পভাবে, আপনি পদ্ধতিটিকে আরও শব্দগতভাবে ঘোষণা করতে পারেন:
// IQuux.hal doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb);
সম্পূর্ণরূপে যোগ্যতাসম্পন্ন গণনা মান
যদি একটি UDT একটি enum প্রকার হয়, তাহলে enum টাইপের প্রতিটি মানের একটি সম্পূর্ণ যোগ্য নাম থাকে যা enum প্রকারের সম্পূর্ণ যোগ্য নাম দিয়ে শুরু হয়, একটি কোলন দ্বারা অনুসরণ করা হয়, তারপরে enum মানের নাম দ্বারা অনুসরণ করা হয়। উদাহরণস্বরূপ, অনুমান করুন প্যাকেজ android.hardware.nfc,
সংস্করণ 1.0
একটি enum প্রকার NfcStatus
সংজ্ঞায়িত করে:
enum NfcStatus { STATUS_OK, STATUS_FAILED };
STATUS_OK
উল্লেখ করার সময়, সম্পূর্ণ যোগ্য নাম হল:
android.hardware.nfc@1.0::NfcStatus:STATUS_OK
সাধারণ সিনট্যাক্স হল PACKAGE @ VERSION :: UDT : VALUE
, যেখানে:
-
PACKAGE @ VERSION :: UDT
হল enum টাইপের জন্য সম্পূর্ণরূপে যোগ্য নাম। -
VALUE
হল মানের নাম৷
অটো-ইনফারেন্স নিয়ম
একটি সম্পূর্ণ যোগ্য UDT নাম নির্দিষ্ট করার প্রয়োজন নেই। একটি UDT নাম নিরাপদে নিম্নলিখিতগুলি বাদ দিতে পারে:
- প্যাকেজ, যেমন
@1.0::IFoo.Type
- উভয় প্যাকেজ এবং সংস্করণ, যেমন
IFoo.Type
HIDL স্বয়ংক্রিয়-হস্তক্ষেপ নিয়ম ব্যবহার করে নামটি সম্পূর্ণ করার চেষ্টা করে (নিম্ন নিয়ম সংখ্যা মানে উচ্চ অগ্রাধিকার)।
নিয়ম 1
যদি কোন প্যাকেজ এবং সংস্করণ প্রদান করা না হয়, একটি স্থানীয় নাম খোঁজার চেষ্টা করা হয়। উদাহরণ:
interface Nfc { typedef string NfcErrorMessage; send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m); };
NfcErrorMessage
স্থানীয়ভাবে দেখা হয়, এবং উপরের typedef
পাওয়া যায়। NfcData
স্থানীয়ভাবেও দেখা হয়, কিন্তু এটি স্থানীয়ভাবে সংজ্ঞায়িত না হওয়ায় নিয়ম 2 এবং 3 ব্যবহার করা হয়। @1.0::NfcStatus
একটি সংস্করণ প্রদান করে, তাই নিয়ম 1 প্রযোজ্য নয়।
নিয়ম 2
যদি নিয়ম 1 ব্যর্থ হয় এবং সম্পূর্ণ যোগ্য নামের একটি উপাদান অনুপস্থিত থাকে (প্যাকেজ, সংস্করণ, বা প্যাকেজ এবং সংস্করণ), তাহলে উপাদানটি বর্তমান প্যাকেজ থেকে তথ্য সহ স্বয়ংক্রিয়ভাবে পূরণ করা হয়। HIDL কম্পাইলার অটোফিল করা সম্পূর্ণ যোগ্য নাম খুঁজে পেতে বর্তমান ফাইলে (এবং সমস্ত আমদানি) দেখে। উপরের উদাহরণটি ব্যবহার করে, অনুমান করুন যে ExtendedNfcData
এর ঘোষণাটি একই প্যাকেজে ( android.hardware.nfc
) NfcData
হিসাবে একই সংস্করণে ( 1.0
) তৈরি করা হয়েছিল, নিম্নরূপ:
struct ExtendedNfcData { NfcData base; // … additional members };
HIDL কম্পাইলার বর্তমান প্যাকেজ থেকে প্যাকেজের নাম এবং সংস্করণের নাম পূরণ করে সম্পূর্ণরূপে যোগ্য UDT নাম android.hardware.nfc@1.0::NfcData
তৈরি করতে। বর্তমান প্যাকেজে নামটি বিদ্যমান থাকায় (ধারণা করা হচ্ছে এটি সঠিকভাবে আমদানি করা হয়েছে), এটি ঘোষণার জন্য ব্যবহৃত হয়।
বর্তমান প্যাকেজে একটি নাম আমদানি করা হয় শুধুমাত্র যদি নিম্নলিখিতগুলির একটি সত্য হয়:
- এটি একটি
import
বিবৃতি দিয়ে স্পষ্টভাবে আমদানি করা হয়। - বর্তমান প্যাকেজে এটি
types.hal
এ সংজ্ঞায়িত করা হয়েছে
NfcData
শুধুমাত্র সংস্করণ নম্বর দ্বারা যোগ্য হলে একই প্রক্রিয়া অনুসরণ করা হয়:
struct ExtendedNfcData { // autofill the current package name (android.hardware.nfc) @1.0::NfcData base; // … additional members };
নিয়ম 3
যদি নিয়ম 2 একটি মিল তৈরি করতে ব্যর্থ হয় (বর্তমান প্যাকেজে UDT সংজ্ঞায়িত করা হয়নি), HIDL কম্পাইলার সমস্ত আমদানি করা প্যাকেজের মধ্যে একটি ম্যাচের জন্য স্ক্যান করে। উপরের উদাহরণটি ব্যবহার করে, ধরে নিন ExtendedNfcData
প্যাকেজ android.hardware.nfc
এর 1.1
সংস্করণে ঘোষণা করা হয়েছে, 1.1
1.0
আমদানি করে ( প্যাকেজ-লেভেল এক্সটেনশনগুলি দেখুন), এবং সংজ্ঞা শুধুমাত্র UDT নামটি নির্দিষ্ট করে:
struct ExtendedNfcData { NfcData base; // … additional members };
কম্পাইলার NfcData
নামের যেকোনো UDT খোঁজে এবং 1.0
সংস্করণে android.hardware.nfc
এ একটি খুঁজে পায়, যার ফলে android.hardware.nfc@1.0::NfcData
এর সম্পূর্ণ যোগ্য UDT পাওয়া যায়। প্রদত্ত আংশিকভাবে যোগ্য UDT-এর জন্য একাধিক মিল পাওয়া গেলে, HIDL কম্পাইলার একটি ত্রুটি ছুড়ে দেয়।
উদাহরণ
নিয়ম 2 ব্যবহার করে, বর্তমান প্যাকেজে সংজ্ঞায়িত একটি আমদানিকৃত প্রকার অন্য প্যাকেজ থেকে আমদানি করা প্রকারের উপর পছন্দ করা হয়:
// hardware/interfaces/foo/1.0/types.hal package android.hardware.foo@1.0; struct S {}; // hardware/interfaces/foo/1.0/IFooCallback.hal package android.hardware.foo@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/types.hal package android.hardware.bar@1.0; typedef string S; // hardware/interfaces/bar/1.0/IFooCallback.hal package android.hardware.bar@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/IBar.hal package android.hardware.bar@1.0; import android.hardware.foo@1.0; interface IBar { baz1(S s); // android.hardware.bar@1.0::S baz2(IFooCallback s); // android.hardware.foo@1.0::IFooCallback };
-
S
কেandroid.hardware.bar@1.0::S
হিসাবে ইন্টারপোলেট করা হয়েছে এবংbar/1.0/types.hal
এ পাওয়া যায় (কারণtypes.hal
স্বয়ংক্রিয়ভাবে আমদানি করা হয়)। -
IFooCallback
কেandroid.hardware.bar@1.0::IFooCallback
বিধি 2 ব্যবহার করে ইন্টারপোলেট করা হয়েছে, কিন্তু এটি খুঁজে পাওয়া যাবে না কারণbar/1.0/IFooCallback.hal
স্বয়ংক্রিয়ভাবে আমদানি করা হয় না (types.hal
হিসাবে)। সুতরাং, নিয়ম 3 এর পরিবর্তেandroid.hardware.foo@1.0::IFooCallback
এ সমাধান করে, যাimport android.hardware.foo@1.0;
)
type.hal
প্রতিটি HIDL প্যাকেজে একটি types.hal
ফাইল রয়েছে যাতে UDTs রয়েছে যা সেই প্যাকেজে অংশগ্রহণকারী সমস্ত ইন্টারফেসের মধ্যে ভাগ করা হয়। HIDL প্রকারগুলি সর্বদা সর্বজনীন; একটি UDT types.hal
এ বা একটি ইন্টারফেস ঘোষণার মধ্যে ঘোষণা করা হোক না কেন, এই ধরনের স্কোপের বাইরে অ্যাক্সেসযোগ্য যেখানে তারা সংজ্ঞায়িত করা হয়েছে। types.hal
একটি প্যাকেজের সর্বজনীন API বর্ণনা করার জন্য নয়, বরং প্যাকেজের মধ্যে সমস্ত ইন্টারফেস দ্বারা ব্যবহৃত UDTs হোস্ট করার জন্য। HIDL-এর প্রকৃতির কারণে, সমস্ত UDT ইন্টারফেসের একটি অংশ।
types.hal
UDTs এবং import
বিবৃতি নিয়ে গঠিত। যেহেতু types.hal
প্যাকেজের প্রতিটি ইন্টারফেসে উপলব্ধ করা হয়েছে (এটি একটি অন্তর্নিহিত আমদানি), এই import
বিবৃতিগুলি সংজ্ঞা অনুসারে প্যাকেজ-স্তর। types.hal
এ UDTs এছাড়াও UDTs এবং এইভাবে আমদানি করা ইন্টারফেস অন্তর্ভুক্ত করতে পারে।
উদাহরণস্বরূপ, একটি IFoo.hal
এর জন্য:
package android.hardware.foo@1.0; // whole package import import android.hardware.bar@1.0; // types only import import android.hardware.baz@1.0::types; // partial imports import android.hardware.qux@1.0::IQux.Quux; // partial imports import android.hardware.quuz@1.0::Quuz;
নিম্নলিখিত আমদানি করা হয়:
-
android.hidl.base@1.0::IBase
(অবশ্যই) -
android.hardware.foo@1.0::types
(অবশ্যই) -
android.hardware.bar@1.0
এ সবকিছু (সমস্ত ইন্টারফেস এবং এরtypes.hal
সহ) -
android.hardware.baz@1.0::types
থেকেtypes.hal
(android.hardware.baz@1.0
এ ইন্টারফেস আমদানি করা হয় না) -
android.hardware.qux@1.0
থেকেIQux.hal
এবংtypes.hal
-
android.hardware.quuz@1.0
থেকেQuuz
(ধরে নিচ্ছি যেQuuz
types.hal
এ সংজ্ঞায়িত করা হয়েছে, সম্পূর্ণtypes.hal
ফাইলটি পার্স করা হয়েছে, কিন্তুQuuz
ছাড়া অন্য প্রকারগুলি আমদানি করা হয় না)।
ইন্টারফেস-স্তরের সংস্করণ
একটি প্যাকেজের মধ্যে প্রতিটি ইন্টারফেস তার নিজস্ব ফাইলে থাকে। ইন্টারফেসটি যে প্যাকেজটির অন্তর্গত তা package
স্টেটমেন্ট ব্যবহার করে ইন্টারফেসের শীর্ষে ঘোষণা করা হয়। প্যাকেজ ঘোষণার পর, শূন্য বা তার বেশি ইন্টারফেস-স্তরের আমদানি (আংশিক বা পুরো-প্যাকেজ) তালিকাভুক্ত হতে পারে। যেমন:
package android.hardware.nfc@1.0;
HIDL-এ, extends
কীওয়ার্ড ব্যবহার করে ইন্টারফেসগুলি অন্যান্য ইন্টারফেস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে। একটি ইন্টারফেস অন্য ইন্টারফেস প্রসারিত করার জন্য, এটি একটি import
বিবৃতি মাধ্যমে এটি অ্যাক্সেস থাকতে হবে. ইন্টারফেসের নাম বাড়ানো হচ্ছে (বেস ইন্টারফেস) উপরে বর্ণিত টাইপ-নেম যোগ্যতার নিয়ম অনুসরণ করে। একটি ইন্টারফেস শুধুমাত্র একটি ইন্টারফেস থেকে উত্তরাধিকারী হতে পারে; HIDL একাধিক উত্তরাধিকার সমর্থন করে না।
নীচের uprev সংস্করণ উদাহরণ নিম্নলিখিত প্যাকেজ ব্যবহার করে:
// types.hal package android.hardware.example@1.0 struct Foo { struct Bar { vec<uint32_t> val; }; }; // IQuux.hal package android.hardware.example@1.0 interface IQuux { fromFooToBar(Foo f) generates (Foo.Bar b); }
Uprev নিয়ম
একটি প্যাকেজ package@major.minor
সংজ্ঞায়িত করতে, হয় A বা সমস্ত B সত্য হতে হবে:
বিধি ক | "একটি স্টার্ট মাইনর ভার্সন": আগের সব ছোট সংস্করণ, package@major.0 , package@major.1 , …, package@major.(minor-1) অবশ্যই সংজ্ঞায়িত করা যাবে না। |
---|
নিয়ম বি | নিম্নলিখিত সব সত্য:
|
---|
নিয়ম A এর কারণে:
- প্যাকেজটি যেকোনো ছোট সংস্করণ নম্বর দিয়ে শুরু হতে পারে (উদাহরণস্বরূপ,
android.hardware.biometrics.fingerprint
@2.1
থেকে শুরু হয়।) - প্রয়োজনীয়তা "
android.hardware.foo@1.0
সংজ্ঞায়িত করা হয়নি" এর মানে হল ডিরেক্টরিhardware/interfaces/foo/1.0
থাকা উচিত নয়।
যাইহোক, নিয়ম A একই প্যাকেজের নামের সাথে একটি প্যাকেজকে প্রভাবিত করে না কিন্তু একটি ভিন্ন প্রধান সংস্করণ (উদাহরণস্বরূপ, android.hardware.camera.device
এ @1.0
এবং @3.2
উভয়ই সংজ্ঞায়িত আছে; @1.0
@3.2
এর সাথে যোগাযোগ করার প্রয়োজন নেই। @1.0
।) তাই, @3.2::IExtFoo
@1.0::IFoo
প্রসারিত করতে পারে।
প্যাকেজের নাম ভিন্ন হলে, package@major.minor::IBar
একটি ভিন্ন নামের ইন্টারফেস থেকে প্রসারিত হতে পারে (উদাহরণস্বরূপ, android.hardware.bar@1.0::IBar
android.hardware.baz@2.2::IBaz
প্রসারিত করতে পারে ) যদি একটি ইন্টারফেস extend
কীওয়ার্ডের সাথে একটি সুপার টাইপ স্পষ্টভাবে ঘোষণা না করে, তবে এটি android.hidl.base@1.0::IBase
( IBase
নিজে ছাড়া) প্রসারিত করে।
B.2 এবং B.3 একই সময়ে অনুসরণ করতে হবে। উদাহরণস্বরূপ, এমনকি যদি android.hardware.foo@1.1::IFoo
প্রসারিত করে android.hardware.foo@1.0::IFoo
নিয়ম B.2 পাস করতে, যদি একটি android.hardware.foo@1.1::IExtBar
android.hardware.foo@1.0::IBar
, এটি এখনও একটি বৈধ uprev নয়।
Uprev ইন্টারফেস
android.hardware.example@1.0
(উপরে সংজ্ঞায়িত) থেকে @1.1
এ উন্নীত করতে:
// types.hal package android.hardware.example@1.1; import android.hardware.example@1.0; // IQuux.hal package android.hardware.example@1.1 interface IQuux extends @1.0::IQuux { fromBarToFoo(Foo.Bar b) generates (Foo f); }
এটি types.hal
এ android.hardware.example
এর সংস্করণ 1.0
এর একটি প্যাকেজ-স্তরের import
। যদিও প্যাকেজের সংস্করণ 1.1
-এ কোনো নতুন UDT যোগ করা হয়নি, সংস্করণ 1.0
-এ UDT-এর উল্লেখ এখনও প্রয়োজন, তাই types.hal
এ প্যাকেজ-স্তরের আমদানি। ( IQuux.hal
এ একটি ইন্টারফেস-স্তরের আমদানির মাধ্যমে একই প্রভাব অর্জন করা যেতে পারে।)
extends @1.0::IQuux
এ IQuux
এর ঘোষণায়, আমরা IQuux
এর যে সংস্করণটি উত্তরাধিকারসূত্রে পাওয়া যাচ্ছে তা নির্দিষ্ট করেছি (দ্ব্যর্থতা নিরসন প্রয়োজন কারণ IQuux
একটি ইন্টারফেস ঘোষণা করতে এবং একটি ইন্টারফেস থেকে উত্তরাধিকারী হতে ব্যবহৃত হয়)। যেহেতু ঘোষণাগুলি কেবলমাত্র এমন নাম যা ঘোষণার সাইটে সমস্ত প্যাকেজ এবং সংস্করণ বৈশিষ্ট্যগুলিকে উত্তরাধিকারী করে, তাই দ্ব্যর্থতা অবশ্যই বেস ইন্টারফেসের নামে হতে হবে; আমরা সম্পূর্ণরূপে যোগ্য UDTও ব্যবহার করতে পারতাম, কিন্তু এটি অপ্রয়োজনীয় হত।
নতুন ইন্টারফেস IQuux
fromFooToBar()
পদ্ধতি পুনরায় ঘোষণা করে না এটি @1.0::IQuux
থেকে উত্তরাধিকারসূত্রে প্রাপ্ত। এটি সহজভাবে fromBarToFoo()
যোগ করা নতুন পদ্ধতি তালিকাভুক্ত করে। HIDL-এ, উত্তরাধিকারসূত্রে প্রাপ্ত পদ্ধতি চাইল্ড ইন্টারফেসে আবার ঘোষণা করা যায় না , তাই IQuux
ইন্টারফেস fromFooToBar()
পদ্ধতিকে স্পষ্টভাবে ঘোষণা করতে পারে না।
উপপ্রেভ কনভেনশন
কখনও কখনও ইন্টারফেসের নামগুলিকে প্রসারিত ইন্টারফেসের নাম পরিবর্তন করতে হবে। আমরা সুপারিশ করি যে enum এক্সটেনশন, স্ট্রাকট এবং ইউনিয়নগুলির একই নাম থাকবে যা তারা প্রসারিত করে যদি না তারা একটি নতুন নাম নিশ্চিত করার জন্য যথেষ্ট আলাদা হয়। উদাহরণ:
// in parent hal file enum Brightness : uint32_t { NONE, WHITE }; // in child hal file extending the existing set with additional similar values enum Brightness : @1.0::Brightness { AUTOMATIC }; // extending the existing set with values that require a new, more descriptive name: enum Color : @1.0::Brightness { HW_GREEN, RAINBOW };
যদি একটি পদ্ধতিতে একটি নতুন শব্দার্থিক নাম থাকতে পারে (উদাহরণস্বরূপ fooWithLocation
) তাহলে এটি পছন্দ করা হয়। অন্যথায়, এটি যা প্রসারিত করছে তার অনুরূপ নামকরণ করা উচিত। উদাহরণস্বরূপ, @1.1::IFoo
এ foo_1_1
পদ্ধতি @1.0::IFoo
তে foo
পদ্ধতির কার্যকারিতা প্রতিস্থাপন করতে পারে যদি এর চেয়ে ভালো বিকল্প নাম না থাকে।
প্যাকেজ-স্তরের সংস্করণ
HIDL সংস্করণ প্যাকেজ স্তরে ঘটে; একটি প্যাকেজ প্রকাশিত হওয়ার পরে, এটি অপরিবর্তনীয় (এর ইন্টারফেসের সেট এবং UDT পরিবর্তন করা যাবে না)। প্যাকেজগুলি একে অপরের সাথে বিভিন্ন উপায়ে সম্পর্কিত হতে পারে, যার সবকটিই ইন্টারফেস-স্তরের উত্তরাধিকারের সংমিশ্রণের মাধ্যমে প্রকাশযোগ্য এবং রচনা দ্বারা UDT-এর নির্মাণ।
যাইহোক, এক ধরনের সম্পর্ক কঠোরভাবে সংজ্ঞায়িত করা হয়েছে এবং অবশ্যই প্রয়োগ করতে হবে: প্যাকেজ-স্তরের পিছনের-সামঞ্জস্যপূর্ণ উত্তরাধিকার । এই পরিস্থিতিতে, প্যারেন্ট প্যাকেজটি হল প্যাকেজটি যা থেকে উত্তরাধিকারসূত্রে প্রাপ্ত হয় এবং চাইল্ড প্যাকেজটি পিতামাতাকে প্রসারিত করে৷ প্যাকেজ-স্তরের পিছনের-সামঞ্জস্যপূর্ণ উত্তরাধিকার নিয়মগুলি নিম্নরূপ:
- প্যারেন্ট প্যাকেজের সমস্ত টপ-লেভেল ইন্টারফেস চাইল্ড প্যাকেজের ইন্টারফেস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত।
- নতুন ইন্টারফেসগুলিও নতুন প্যাকেজ যোগ করা যেতে পারে (অন্যান্য প্যাকেজে অন্যান্য ইন্টারফেসের সাথে সম্পর্ক সম্পর্কে কোন সীমাবদ্ধতা নেই)।
- নতুন ডাটা টাইপগুলিও ব্যবহার করার জন্য যুক্ত করা যেতে পারে আপপ্রেভ'ড বিদ্যমান ইন্টারফেসের নতুন পদ্ধতি বা নতুন ইন্টারফেসের মাধ্যমে।
এই নিয়মগুলি HIDL ইন্টারফেস-স্তরের উত্তরাধিকার এবং UDT কম্পোজিশন ব্যবহার করে প্রয়োগ করা যেতে পারে, তবে এই সম্পর্কগুলি একটি পিছনের-সামঞ্জস্যপূর্ণ প্যাকেজ এক্সটেনশন গঠন করে তা জানার জন্য মেটা-স্তরের জ্ঞান প্রয়োজন। এই জ্ঞান নিম্নরূপ অনুমান করা হয়:
যদি একটি প্যাকেজ এই প্রয়োজনীয়তা পূরণ করে, hidl-gen
ব্যাকওয়ার্ড-কম্প্যাটিবিলিটি নিয়ম প্রয়োগ করে।