এইচআইডিএল

HAL ইন্টারফেস ডেফিনিশন ল্যাঙ্গুয়েজ বা HIDL হল একটি ইন্টারফেস বর্ণনা ভাষা (IDL) যা একটি HAL এবং এর ব্যবহারকারীদের মধ্যে ইন্টারফেস নির্দিষ্ট করতে। HIDL ইন্টারফেস এবং প্যাকেজগুলিতে সংগৃহীত প্রকার এবং পদ্ধতি কলগুলি নির্দিষ্ট করার অনুমতি দেয়। আরও বিস্তৃতভাবে, HIDL হল কোডবেসের মধ্যে যোগাযোগের জন্য একটি সিস্টেম যা স্বাধীনভাবে সংকলিত হতে পারে।

HIDL আন্তঃপ্রক্রিয়া যোগাযোগ (IPC) এর জন্য ব্যবহার করার উদ্দেশ্যে করা হয়েছে। এইচডিএল দিয়ে তৈরি এইচএএলকে বাইন্ডারাইজড এইচএএল বলা হয় যে তারা বাইন্ডার ইন্টার-প্রসেস কমিউনিকেশন (আইপিসি) কল ব্যবহার করে অন্যান্য আর্কিটেকচার স্তরের সাথে যোগাযোগ করতে পারে। বাইন্ডারাইজড এইচএএলগুলি ক্লায়েন্ট থেকে একটি পৃথক প্রক্রিয়ায় চলে যা তাদের ব্যবহার করে। লাইব্রেরিগুলির জন্য যেগুলি অবশ্যই একটি প্রক্রিয়ার সাথে লিঙ্ক করা উচিত, একটি পাসথ্রু মোডও উপলব্ধ (জাভাতে সমর্থিত নয়)।

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

পরিভাষা

এই বিভাগটি নিম্নলিখিত HIDL-সম্পর্কিত শর্তাবলী ব্যবহার করে:

binderized নির্দেশ করে যে HIDL প্রসেসগুলির মধ্যে দূরবর্তী পদ্ধতি কলের জন্য ব্যবহার করা হচ্ছে, একটি বাইন্ডারের মতো মেকানিজমের মাধ্যমে প্রয়োগ করা হয়েছে। এছাড়াও পাসথ্রু দেখুন.
কলব্যাক, অ্যাসিঙ্ক্রোনাস এইচএএল ব্যবহারকারীর দ্বারা পরিবেশিত ইন্টারফেস, এইচএএলকে পাস করা হয় (একটি HIDL পদ্ধতি ব্যবহার করে), এবং যে কোনও সময় ডেটা ফেরত দেওয়ার জন্য HAL দ্বারা ডাকা হয়।
কলব্যাক, সিঙ্ক্রোনাস একটি সার্ভারের HIDL পদ্ধতি বাস্তবায়ন থেকে ক্লায়েন্টের কাছে ডেটা ফেরত দেয়। অব্যবহৃত পদ্ধতি যা অকার্যকর বা একটি একক আদিম মান প্রদান করে।
ক্লায়েন্ট প্রক্রিয়া যা একটি নির্দিষ্ট ইন্টারফেসের পদ্ধতি কল করে। একটি HAL বা Android ফ্রেমওয়ার্ক প্রক্রিয়া একটি ইন্টারফেসের একটি ক্লায়েন্ট এবং অন্য একটি সার্ভার হতে পারে। এছাড়াও পাসথ্রু দেখুন.
প্রসারিত একটি ইন্টারফেস নির্দেশ করে যা অন্য ইন্টারফেসে পদ্ধতি এবং/অথবা প্রকার যোগ করে। একটি ইন্টারফেস শুধুমাত্র একটি অন্য ইন্টারফেস প্রসারিত করতে পারে। একই প্যাকেজের নামে একটি ছোট সংস্করণ বৃদ্ধির জন্য বা একটি নতুন প্যাকেজের জন্য (যেমন একটি বিক্রেতা এক্সটেনশন) একটি পুরানো প্যাকেজ তৈরি করতে ব্যবহার করা যেতে পারে।
উৎপন্ন করে একটি ইন্টারফেস পদ্ধতি নির্দেশ করে যা ক্লায়েন্টকে মান প্রদান করে। একটি অ-আদি মান, বা একাধিক মান ফেরত দিতে, একটি সিঙ্ক্রোনাস কলব্যাক ফাংশন তৈরি করা হয়।
ইন্টারফেস পদ্ধতি এবং প্রকারের সংগ্রহ। C++ বা জাভাতে একটি ক্লাসে অনুবাদ করা হয়েছে। একটি ইন্টারফেসের সমস্ত পদ্ধতি একই দিকে বলা হয়: একটি ক্লায়েন্ট প্রক্রিয়া একটি সার্ভার প্রক্রিয়া দ্বারা বাস্তবায়িত পদ্ধতিগুলিকে আহ্বান করে।
একপথ একটি HIDL পদ্ধতিতে প্রয়োগ করা হলে, নির্দেশ করে যে পদ্ধতিটি কোন মান প্রদান করে না এবং ব্লক করে না।
প্যাকেজ একটি সংস্করণ ভাগ করে নেওয়া ইন্টারফেস এবং ডেটা প্রকারের সংগ্রহ।
পাসথ্রু HIDL-এর মোড যেখানে সার্ভার একটি শেয়ার্ড লাইব্রেরি, ক্লায়েন্ট দ্বারা dlopen ed. পাসথ্রু মোডে, ক্লায়েন্ট এবং সার্ভার একই প্রক্রিয়া কিন্তু আলাদা কোডবেস। শুধুমাত্র HIDL মডেলে উত্তরাধিকার কোডবেস আনতে ব্যবহৃত হয়। আরও দেখুন Binderized .
সার্ভার প্রক্রিয়া যা একটি ইন্টারফেসের পদ্ধতি প্রয়োগ করে। এছাড়াও পাসথ্রু দেখুন.
পরিবহন HIDL অবকাঠামো যা সার্ভার এবং ক্লায়েন্টের মধ্যে ডেটা স্থানান্তর করে।
সংস্করণ একটি প্যাকেজের সংস্করণ। দুটি পূর্ণসংখ্যা নিয়ে গঠিত, বড় এবং ছোট। ছোট সংস্করণ বৃদ্ধি (কিন্তু পরিবর্তন নয়) প্রকার এবং পদ্ধতি যোগ করতে পারে।

HIDL ডিজাইন

HIDL-এর লক্ষ্য হল HALs পুনর্নির্মাণ না করেই Android ফ্রেমওয়ার্ক প্রতিস্থাপন করা যেতে পারে। এইচএএলগুলি বিক্রেতা বা এসওসি নির্মাতাদের দ্বারা তৈরি করা হয় এবং ডিভাইসে একটি /vendor পার্টিশনে রাখে, যার ফলে অ্যান্ড্রয়েড ফ্রেমওয়ার্ককে সক্রিয় করে, তার নিজস্ব পার্টিশনে, HALগুলি পুনরায় কম্পাইল না করে একটি OTA দিয়ে প্রতিস্থাপন করা যায়।

HIDL ডিজাইন নিম্নলিখিত উদ্বেগের ভারসাম্য বজায় রাখে:

  • ইন্টারঅপারেবিলিটি বিভিন্ন স্থাপত্য, টুলচেইন এবং বিল্ড কনফিগারেশনের সাথে সংকলিত হতে পারে এমন প্রক্রিয়াগুলির মধ্যে নির্ভরযোগ্যভাবে আন্তঃঅপারেবল ইন্টারফেস তৈরি করুন। HIDL ইন্টারফেসগুলি সংস্করণ করা হয়েছে এবং সেগুলি প্রকাশিত হওয়ার পরে পরিবর্তন করা যাবে না।
  • কর্মদক্ষতা । এইচআইডিএল কপি অপারেশনের সংখ্যা কমানোর চেষ্টা করে। HIDL-সংজ্ঞায়িত ডেটা C++ স্ট্যান্ডার্ড লেআউট ডেটা স্ট্রাকচারে C++ কোডে বিতরণ করা হয় যা আনপ্যাকিং ছাড়াই ব্যবহার করা যেতে পারে। HIDL শেয়ার্ড মেমরি ইন্টারফেসও প্রদান করে এবং, যেহেতু RPC গুলি স্বাভাবিকভাবেই কিছুটা ধীরগতির, তাই HIDL RPC কল ব্যবহার না করেই ডেটা স্থানান্তর করার দুটি উপায় সমর্থন করে: শেয়ার্ড মেমরি এবং একটি ফাস্ট মেসেজ কিউ (FMQ)।
  • স্বজ্ঞাত । HIDL শুধুমাত্র RPC-এর জন্য in ব্যবহার করে মেমরির মালিকানার কণ্টকাকীর্ণ সমস্যাগুলি এড়ায় ( এন্ড্রয়েড ইন্টারফেস ডেফিনিশন ল্যাঙ্গুয়েজ (এআইডিএল) দেখুন); যে মানগুলি পদ্ধতিগুলি থেকে দক্ষতার সাথে ফেরত দেওয়া যায় না সেগুলি কলব্যাক ফাংশনের মাধ্যমে ফেরত দেওয়া হয়। ট্রান্সফারের জন্য HIDL-এ ডেটা পাঠানো বা HIDL থেকে ডেটা গ্রহণ করা ডেটার মালিকানা পরিবর্তন করে না—মালিকানা সর্বদা কলিং ফাংশনের সাথে থাকে। ডেটা শুধুমাত্র কল ফাংশনের সময়কালের জন্য টিকে থাকতে হবে এবং কল ফাংশন রিটার্ন করার সাথে সাথেই ধ্বংস হয়ে যেতে পারে।

পাসথ্রু মোড ব্যবহার করুন

অ্যান্ড্রয়েডের আগের সংস্করণগুলিকে অ্যান্ড্রয়েড O-তে চলমান ডিভাইসগুলিকে আপডেট করতে, আপনি একটি নতুন HIDL ইন্টারফেসে প্রচলিত (এবং উত্তরাধিকারী) উভয় HAL-কে মুড়ে দিতে পারেন যা বাইন্ডারাইজড এবং একই-প্রক্রিয়া (পাসথ্রু) মোডে HAL-কে পরিবেশন করে৷ এই মোড়কটি HAL এবং Android ফ্রেমওয়ার্ক উভয়ের জন্যই স্বচ্ছ৷

পাসথ্রু মোড শুধুমাত্র C++ ক্লায়েন্ট এবং বাস্তবায়নের জন্য উপলব্ধ। অ্যান্ড্রয়েডের আগের সংস্করণে চলমান ডিভাইসগুলিতে জাভাতে HAL লেখা থাকে না, তাই জাভা HALগুলি সহজাতভাবে বাইন্ডারাইজড।

যখন একটি .hal ফাইল কম্পাইল করা হয়, hidl-gen বাইন্ডার যোগাযোগের জন্য ব্যবহৃত হেডার ছাড়াও একটি অতিরিক্ত পাসথ্রু হেডার ফাইল BsFoo.h তৈরি করে; এই হেডার dlopen ed হতে ফাংশন সংজ্ঞায়িত করে। যেহেতু পাসথ্রু এইচএএলগুলি একই প্রক্রিয়ায় চালিত হয় যেখানে তাদের বলা হয়, বেশিরভাগ ক্ষেত্রে পাসথ্রু পদ্ধতিগুলি সরাসরি ফাংশন কল (একই থ্রেড) দ্বারা আহ্বান করা হয়। oneway পদ্ধতিগুলি তাদের নিজস্ব থ্রেডে চলে কারণ সেগুলি HAL-এর প্রক্রিয়া করার জন্য অপেক্ষা করার উদ্দেশ্যে নয় (এর মানে হল যে কোনও HAL যা পাসথ্রু মোডে oneway পদ্ধতি ব্যবহার করে থ্রেড-সেফ হতে হবে)।

একটি IFoo.hal প্রদত্ত, BsFoo.h অতিরিক্ত বৈশিষ্ট্য প্রদানের জন্য HIDL-উত্পাদিত পদ্ধতিগুলিকে মোড়ক করে (যেমন oneway লেনদেন অন্য থ্রেডে চালানো)। এই ফাইলটি BpFoo.h এর অনুরূপ, তবে বাইন্ডার ব্যবহার করে IPC কল করার পরিবর্তে, পছন্দসই ফাংশনগুলি সরাসরি আহ্বান করা হয়। HAL-এর ভবিষ্যত বাস্তবায়ন একাধিক বাস্তবায়ন প্রদান করতে পারে , যেমন FooFast HAL এবং একটি FooAccurate HAL। এই ধরনের ক্ষেত্রে, প্রতিটি অতিরিক্ত বাস্তবায়নের জন্য একটি ফাইল তৈরি করা হবে (যেমন, PTFooFast.cpp এবং PTFooAccurate.cpp )।

বাইন্ডারাইজিং পাসথ্রু HALs

আপনি পাসথ্রু মোড সমর্থনকারী HAL বাস্তবায়ন বাইন্ডারাইজ করতে পারেন। একটি HAL ইন্টারফেস abcd@MN::IFoo দেওয়া হলে, দুটি প্যাকেজ তৈরি করা হয়:

  • abcd@MN::IFoo-impl । HAL এর বাস্তবায়ন ধারণ করে এবং IFoo* HIDL_FETCH_IFoo(const char* name) ফাংশন প্রকাশ করে। লিগ্যাসি ডিভাইসগুলিতে, এই প্যাকেজটি dlopen ed হয় এবং বাস্তবায়নটি HIDL_FETCH_IFoo ব্যবহার করে তাৎক্ষণিকভাবে করা হয়। আপনি hidl-gen এবং -Lc++-impl এবং -Landroidbp-impl ব্যবহার করে বেস কোড তৈরি করতে পারেন।
  • abcd@MN::IFoo-service । পাসথ্রু HAL খোলে এবং নিজেকে একটি বাইন্ডারাইজড পরিষেবা হিসাবে নিবন্ধিত করে, একই HAL বাস্তবায়নকে পাসথ্রু এবং বাইন্ডারাইজড উভয় হিসাবে ব্যবহার করতে সক্ষম করে।

IFoo টাইপ দেওয়া হলে, আপনি IFoo এর একটি উদাহরণে অ্যাক্সেস পেতে sp<IFoo> IFoo::getService(string name, bool getStub) কল করতে পারেন। getStub সত্য হলে, getService শুধুমাত্র পাসথ্রু মোডে HAL খোলার চেষ্টা করে। getStub মিথ্যা হলে, getService একটি বাইন্ডারাইজড পরিষেবা খোঁজার চেষ্টা করে; যদি এটি ব্যর্থ হয়, তাহলে এটি পাসথ্রু পরিষেবাটি খুঁজে বের করার চেষ্টা করে। defaultPassthroughServiceImplementation ছাড়া getStub প্যারামিটার কখনই ব্যবহার করা উচিত নয়। (Android O দিয়ে চালু হওয়া ডিভাইসগুলি সম্পূর্ণরূপে বাইন্ডারাইজড ডিভাইস, তাই পাসথ্রু মোডে একটি পরিষেবা খোলার অনুমতি নেই।)

HIDL ব্যাকরণ

ডিজাইন অনুসারে, HIDL ভাষা C এর অনুরূপ (কিন্তু C প্রিপ্রসেসর ব্যবহার করে না)। নীচে বর্ণিত নয় এমন সমস্ত বিরাম চিহ্ন ( = এবং | এর সুস্পষ্ট ব্যবহার বাদ দিয়ে) ব্যাকরণের অংশ।

দ্রষ্টব্য: HIDL কোড শৈলীর বিস্তারিত জানার জন্য, কোড স্টাইল গাইড দেখুন।

  • /** */ একটি ডকুমেন্টেশন মন্তব্য নির্দেশ করে। এগুলি শুধুমাত্র টাইপ, পদ্ধতি, ক্ষেত্র এবং enum মান ঘোষণার ক্ষেত্রে প্রয়োগ করা যেতে পারে।
  • /* */ একটি মাল্টিলাইন মন্তব্য নির্দেশ করে।
  • // লাইনের শেষে একটি মন্তব্য নির্দেশ করে। সরাইয়া // , newlines অন্য যে কোনো হোয়াইটস্পেস হিসাবে একই.
  • নীচের ব্যাকরণের উদাহরণে, // থেকে লাইনের শেষ পর্যন্ত পাঠ্য ব্যাকরণের অংশ নয় বরং ব্যাকরণের উপর একটি মন্তব্য।
  • [empty] মানে শব্দটি খালি হতে পারে।
  • ? একটি আক্ষরিক বা শব্দ অনুসরণ করা মানে এটি ঐচ্ছিক।
  • ... নির্দেশিত হিসাবে বিচ্ছিন্ন বিরাম চিহ্ন সহ শূন্য বা তার বেশি আইটেম ধারণকারী ক্রম নির্দেশ করে। HIDL-এ কোন বৈচিত্র্যময় যুক্তি নেই।
  • কমা পৃথক ক্রম উপাদান.
  • সেমিকোলন শেষ উপাদান সহ প্রতিটি উপাদানকে শেষ করে।
  • UPPERCASE একটি নন-টার্মিনাল।
  • italics হল একটি টোকেন পরিবার যেমন integer বা identifier (স্ট্যান্ডার্ড সি পার্সিং নিয়ম)।
  • constexpr হল একটি C স্টাইলের ধ্রুবক অভিব্যক্তি (যেমন 1 + 1 এবং 1L << 3 )।
  • import_name হল একটি প্যাকেজ বা ইন্টারফেসের নাম, HIDL সংস্করণে বর্ণিত হিসাবে যোগ্য।
  • ছোট হাতের words আক্ষরিক টোকেন।

উদাহরণ:

ROOT =
    PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... }  // not for types.hal
  | PACKAGE IMPORTS ITEM ITEM...  // only for types.hal; no method definitions

ITEM =
    ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?;
  |  safe_union identifier { UFIELD; UFIELD; ...};
  |  struct identifier { SFIELD; SFIELD; ...};  // Note - no forward declarations
  |  union identifier { UFIELD; UFIELD; ...};
  |  enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar
  |  typedef TYPE identifier;

VERSION = integer.integer;

PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION;

PREAMBLE = interface identifier EXTENDS

EXTENDS = <empty> | extends import_name  // must be interface, not package

GENERATES = generates (FIELD, FIELD ...)

// allows the Binder interface to be used as a type
// (similar to typedef'ing the final identifier)
IMPORTS =
   [empty]
  |  IMPORTS import import_name;

TYPE =
  uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t |
 float | double | bool | string
|  identifier  // must be defined as a typedef, struct, union, enum or import
               // including those defined later in the file
|  memory
|  pointer
|  vec<TYPE>
|  bitfield<TYPE>  // TYPE is user-defined enum
|  fmq_sync<TYPE>
|  fmq_unsync<TYPE>
|  TYPE[SIZE]

FIELD =
   TYPE identifier

UFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...};
  |  struct identifier { FIELD; FIELD; ...};
  |  union identifier { FIELD; FIELD; ...};
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SIZE =  // Must be greater than zero
     constexpr

ANNOTATIONS =
     [empty]
  |  ANNOTATIONS ANNOTATION

ANNOTATION =
  |  @identifier
  |  @identifier(VALUE)
  |  @identifier(ANNO_ENTRY, ANNO_ENTRY  ...)

ANNO_ENTRY =
     identifier=VALUE

VALUE =
     "any text including \" and other escapes"
  |  constexpr
  |  {VALUE, VALUE ...}  // only in annotations

ENUM_ENTRY =
     identifier
  |  identifier = constexpr