HIDL C++

Android O ডিভাইস-স্বাধীন অ্যান্ড্রয়েড প্ল্যাটফর্ম এবং ডিভাইস- এবং বিক্রেতা-নির্দিষ্ট কোডের মধ্যে স্পষ্ট ইন্টারফেস সংজ্ঞায়িত করতে Android OS-কে পুনরায় স্থপতি করে। অ্যান্ড্রয়েড ইতিমধ্যেই HAL ইন্টারফেসের আকারে এই ধরনের অনেক ইন্টারফেসকে সংজ্ঞায়িত করেছে, hardware/libhardware সি হেডার হিসেবে সংজ্ঞায়িত করা হয়েছে। HIDL এই HAL ইন্টারফেসগুলিকে স্থিতিশীল, সংস্করণযুক্ত ইন্টারফেসগুলির সাথে প্রতিস্থাপন করে, যা C++ (নীচে বর্ণিত) বা জাভাতে ক্লায়েন্ট- এবং সার্ভার-সাইড HIDL ইন্টারফেস হতে পারে।

এই বিভাগের পৃষ্ঠাগুলি HIDL ইন্টারফেসের C++ বাস্তবায়ন বর্ণনা করে, যার মধ্যে hidl-gen কম্পাইলার দ্বারা HIDL .hal ফাইলগুলি থেকে স্বয়ংক্রিয়ভাবে তৈরি হওয়া ফাইলগুলির বিবরণ, এই ফাইলগুলি কীভাবে প্যাকেজ করা হয় এবং কীভাবে এই ফাইলগুলিকে C++ কোডের সাথে একীভূত করা যায়। তাদের ব্যবহার করে।

ক্লায়েন্ট এবং সার্ভার বাস্তবায়ন

HIDL ইন্টারফেসে ক্লায়েন্ট এবং সার্ভার বাস্তবায়ন রয়েছে:

  • একটি এইচআইডিএল ইন্টারফেসের একটি ক্লায়েন্ট হল সেই কোড যা ইন্টারফেসকে কল করার পদ্ধতি ব্যবহার করে।
  • একটি সার্ভার হল একটি HIDL ইন্টারফেসের বাস্তবায়ন যা ক্লায়েন্টদের কাছ থেকে কল গ্রহণ করে এবং ফলাফল প্রদান করে (যদি প্রয়োজন হয়)।

libhardware HALs থেকে HIDL HAL-তে রূপান্তর করার সময়, HAL বাস্তবায়ন সার্ভারে পরিণত হয় এবং HAL-এ কল করার প্রক্রিয়াটি ক্লায়েন্টে পরিণত হয়। ডিফল্ট বাস্তবায়ন পাসথ্রু এবং বাইন্ডারাইজড এইচএএল উভয়ই পরিবেশন করতে পারে এবং সময়ের সাথে সাথে পরিবর্তন হতে পারে:

চিত্র 1. উত্তরাধিকারী HAL-এর জন্য উন্নয়ন অগ্রগতি।

HAL ক্লায়েন্ট তৈরি করা হচ্ছে

মেকফাইলে HAL লাইব্রেরি অন্তর্ভুক্ত করে শুরু করুন:

  • তৈরি করুন: LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
  • Soong: shared_libs: [ …, android.hardware.nfc@1.0 ]

এর পরে, HAL হেডার ফাইলগুলি অন্তর্ভুক্ত করুন:

#include <android/hardware/nfc/1.0/IFoo.h>
…
// in code:
sp<IFoo> client = IFoo::getService();
client->doThing();

HAL সার্ভার তৈরি করা হচ্ছে

এইচএএল ইমপ্লিমেন্টেশন তৈরি করতে, আপনার কাছে অবশ্যই .hal ফাইল থাকতে হবে যা আপনার HAL-এর প্রতিনিধিত্ব করে এবং ইতিমধ্যেই আপনার HAL-এর জন্য hidl-gen-Lmakefile বা -Landroidbp ব্যবহার করে মেকফাইল তৈরি করেছে ( ./hardware/interfaces/update-makefiles.sh এর জন্য এটি করে অভ্যন্তরীণ HAL ফাইল এবং একটি ভাল রেফারেন্স)। libhardware থেকে HAL-এর উপর স্থানান্তর করার সময়, আপনি c2hal ব্যবহার করে সহজেই এই কাজটি অনেক করতে পারেন।

আপনার HAL বাস্তবায়নের জন্য প্রয়োজনীয় ফাইল তৈরি করতে:

PACKAGE=android.hardware.nfc@1.0
LOC=hardware/interfaces/nfc/1.0/default/
m -j hidl-gen
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport $PACKAGE

HAL-এর পাসথ্রু মোডে কাজ করার জন্য, আপনার কাছে অবশ্যই HIDL_FETCH_IModuleName ফাংশনটি থাকতে হবে যা /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so যেখানে OPTIONAL_IDENTIFIER হল একটি স্ট্রিং যা পাসথ্রু বাস্তবায়নকে চিহ্নিত করে৷ পাসথ্রু মোডের প্রয়োজনীয়তাগুলি উপরের কমান্ডগুলির দ্বারা স্বয়ংক্রিয়ভাবে পূরণ করা হয়, যা android.hardware.nfc@1.0-impl টার্গেটও তৈরি করে, তবে যেকোনো এক্সটেনশন ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, android.hardware.nfc@1.0-impl-foo নিজেকে আলাদা করতে -foo ব্যবহার করে।

যদি একটি HAL একটি ছোট সংস্করণ বা অন্য HAL-এর একটি এক্সটেনশন হয়, তাহলে এই বাইনারি নামকরণের জন্য বেস HAL ব্যবহার করা উচিত। উদাহরণস্বরূপ, android.hardware.graphics.mapper@2.1 বাস্তবায়নগুলি এখনও android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER ) নামে একটি বাইনারিতে থাকা উচিত। সাধারণত, এখানে OPTIONAL_IDENTIFIER প্রকৃত HAL সংস্করণ অন্তর্ভুক্ত করবে। এইভাবে বাইনারি নামকরণ করে, 2.0 ক্লায়েন্ট সরাসরি এটি পুনরুদ্ধার করতে পারে এবং 2.1 ক্লায়েন্ট বাস্তবায়নটি আপকাস্ট করতে পারে।

এর পরে, কার্যকারিতা সহ স্টাবগুলি পূরণ করুন এবং একটি ডেমন সেটআপ করুন। উদাহরণ ডেমন কোড (সমর্থক পাসথ্রু):

#include <hidl/LegacySupport.h>

int main(int /* argc */, char* /* argv */ []) {
    return defaultPassthroughServiceImplementation<INfc>("nfc");
}

defaultPassthroughServiceImplementation প্রদত্ত -impl লাইব্রেরি dlopen() করবে এবং এটি একটি বাইন্ডারাইজড পরিষেবা হিসাবে প্রদান করবে। উদাহরণ ডেমন কোড (বিশুদ্ধ বাইন্ডারাইজড পরিষেবার জন্য):

int main(int /* argc */, char* /* argv */ []) {
    // This function must be called before you join to ensure the proper
    // number of threads are created. The threadpool will never exceed
    // size one because of this call.
    ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/);

    sp<INfc> nfc = new Nfc();
    const status_t status = nfc->registerAsService();
    if (status != ::android::OK) {
        return 1; // or handle error
    }

    // Adds this thread to the threadpool, resulting in one total
    // thread in the threadpool. We could also do other things, but
    // would have to specify 'false' to willJoin in configureRpcThreadpool.
    ::android::hardware::joinRpcThreadpool();
    return 1; // joinRpcThreadpool should never return
}

এই ডেমন সাধারণত $PACKAGE + "-service-suffix" এ থাকে (উদাহরণস্বরূপ, android.hardware.nfc@1.0-service ), কিন্তু এটি যে কোনো জায়গায় হতে পারে। HAL-এর একটি নির্দিষ্ট শ্রেণীর জন্য sepolicy হল অ্যাট্রিবিউট hal_<module> (উদাহরণস্বরূপ, hal_nfc) । এই অ্যাট্রিবিউটটি অবশ্যই ডেমনে প্রয়োগ করা উচিত যা একটি নির্দিষ্ট HAL চালায় (যদি একই প্রক্রিয়া একাধিক HAL-কে পরিবেশন করে, একাধিক বৈশিষ্ট্য এতে প্রয়োগ করা যেতে পারে)।