سبک کد HIDL شبیه کد ++C در چارچوب اندروید است که دارای تورفتگیهای ۴ فضایی و نام فایلهای مختلط است. اعلانهای بسته، واردات و رشتههای اسناد مشابه موارد موجود در جاوا هستند، با تغییرات جزئی.
مثالهای زیر برای IFoo.hal
و types.hal
سبکهای کد HIDL را نشان میدهند و پیوندهای سریعی به جزئیات هر سبک ارائه میدهند ( IFooClientCallback.hal
، IBar.hal
و IBaz.hal
حذف شدهاند).
hardware/interfaces/foo/1.0/IFoo.hal |
---|
/* * (License Notice) */ package android.hardware.foo@1.0; import android.hardware.bar@1.0::IBar; import IBaz; import IFooClientCallback; /** * IFoo is an interface that… */ interface IFoo { /** * This is a multiline docstring. * * @return result 0 if successful, nonzero otherwise. */ foo() generates (FooStatus result); /** * Restart controller by power cycle. * * @param bar callback interface that… * @return result 0 if successful, nonzero otherwise. */ powerCycle(IBar bar) generates (FooStatus result); /** Single line docstring. */ baz(); /** * The bar function. * * @param clientCallback callback after function is called * @param baz related baz object * @param data input data blob */ bar(IFooClientCallback clientCallback, IBaz baz, FooData data); }; |
hardware/interfaces/foo/1.0/types.hal |
---|
/* * (License Notice) */ package android.hardware.foo@1.0; /** Replied status. */ enum Status : int32_t { OK, /* invalid arguments */ ERR_ARG, /* note, no transport related errors */ ERR_UNKNOWN = -1, }; struct ArgData { int32_t[20] someArray; vec<uint8_t> data; }; |
نام توابع، نام متغیرها و نام فایل ها باید توصیفی باشند. از اختصار بیش از حد خودداری کنید کلمات اختصاری را به عنوان کلمات در نظر بگیرید (برای مثال، به جای INFC
از INfc
استفاده کنید).
ساختار دایرکتوری باید به صورت زیر ظاهر شود:
-
ROOT-DIRECTORY
-
MODULE
-
SUBMODULE
(اختیاری، می تواند بیش از یک سطح باشد)-
VERSION
-
Android.mk
-
I INTERFACE_1 .hal
-
I INTERFACE_2 .hal
-
…
-
I INTERFACE_N .hal
-
types.hal
(اختیاری)
-
-
-
-
جایی که:
-
ROOT-DIRECTORY
عبارت است از:-
hardware/interfaces
برای بسته های اصلی HIDL. -
vendor/ VENDOR /interfaces
بستههای فروشنده، جایی کهVENDOR
به یک فروشنده SoC یا یک OEM/ODM اشاره دارد.
-
-
MODULE
باید یک کلمه کوچک باشد که زیرسیستم را توصیف کند (مثلاnfc
). اگر بیش از یک کلمه مورد نیاز است، ازSUBMODULE
تودرتو استفاده کنید. می تواند بیش از یک سطح از تودرتو وجود داشته باشد. -
VERSION
باید دقیقاً همان نسخه (major.minor) باشد که در نسخه ها توضیح داده شده است. -
I INTERFACE_X
باید نام رابط باUpperCamelCase
/PascalCase
(به عنوان مثال،INfc
) باشد همانطور که در نامهای رابط توضیح داده شده است.
مثال:
-
hardware/interfaces
-
nfc
-
1.0
-
Android.mk
-
INfc.hal
-
INfcClientCallback.hal
-
types.hal
-
-
-
توجه: همه فایل ها باید دارای مجوزهای غیر قابل اجرا (در Git) باشند. نام بستهها باید از قالب نام کاملاً واجد شرایط زیر (FQN) استفاده کنند (به آن جایی که: FQN همیشه در اعلامیه های بسته استفاده می شود. نسخه ها باید فرمت زیر را داشته باشند: هر دو نسخه MAJOR و MINOR باید یک عدد صحیح باشند. HIDL از قوانین نسخهسازی معنایی استفاده میکند. یک واردات دارای یکی از سه قالب زیر است: فقط در صورت لزوم از نام های کاملا واجد شرایط برای وارد کردن نوع تعریف شده توسط کاربر استفاده کنید. اگر نوع واردات در همان بسته است، در فایل دیگری تحت پس از اعلام بسته (قبل از واردات) از یک خط خالی استفاده کنید. هر واردات باید یک خط را اشغال کند و نباید تورفتگی داشته باشد. گروه بندی واردات به ترتیب زیر: از یک خط خالی بین گروه ها استفاده کنید. در داخل هر گروه، واردات را بر اساس حروف الفبا مرتب کنید. مثال: نام رابط باید با یک برای نام توابع، آرگومان ها و نام متغیرهای برگشتی، از برای نامهای فیلد ساختار یا اتحاد، از نام تایپ به تعاریف ساختار یا اتحادیه، تعاریف نوع enum و مقادیر Enum باید نکته: نوع زیربنایی یک نوع enum به صراحت بعد از کولون اعلام می شود. از آنجایی که به کامپایلر وابسته نیست، استفاده از نوع enum واقعی واضح تر است. برای نامهای کاملا واجد شرایط برای مقادیر enum، یک دونقطه بین نام نوع enum و نام مقدار enum استفاده میشود: در داخل یک نام کاملا واجد شرایط نباید فاصله وجود داشته باشد. فقط در صورت لزوم از یک نام کاملاً واجد شرایط استفاده کنید و قطعات غیر ضروری را حذف کنید. مثال: برای یک کامنت تک خطی، هر فایل را با اعلامیه مجوز مناسب شروع کنید. برای HAL های اصلی، این باید مجوز AOSP Apache در میتوانید بهصورت اختیاری، یک خط خالی بعد از اخطار مجوز، و به دنبال آن اطلاعات تغییرات/نسخهگذاری قرار دهید. از کامنت های چند خطی TODO ها باید شامل رشته نظرات TODO فقط در طول توسعه مجاز است. آنها نباید در رابط های منتشر شده وجود داشته باشند. برای رشته های اسناد چند خطی و تک خطی رشتههای اسناد برای رابطها باید مکانیسمهای کلی رابط، منطق طراحی، هدف، و غیره را توصیف کنند. برای هر پارامتر/مقدار بازگشتی باید s مثال: قوانین قالب بندی کلی عبارتند از: اعلان بسته باید در بالای فایل پس از اعلان مجوز باشد، باید کل خط را اشغال کند و نباید تورفتگی داشته باشد. بسته ها با استفاده از قالب زیر اعلام می شوند (برای قالب بندی نام، به نام بسته ها مراجعه کنید): مثال: نام تابع، پارامترها، اگر در یک خط قرار نمیگیرند، سعی کنید پارامترها و مقادیر برگردانده را در یک سطح تورفتگی قرار دهید و توضیحات بیشتر: از قالب زیر برای حاشیه نویسی استفاده کنید: حاشیه نویسی ها را به ترتیب حروف الفبا مرتب کنید و از فاصله های اطراف علامت های مساوی استفاده کنید. مثال: اطمینان حاصل کنید که یک حاشیه نویسی کل خط را اشغال می کند. مثال ها: اگر حاشیه نویسی ها در یک خط قرار نمی گیرند، با 8 فاصله تورفتگی کنید. مثال: اگر کل آرایه مقدار نمی تواند در یک خط قرار گیرد، پس از پرانتزهای باز اگر کل آرایه مقدار می تواند در یک خط قرار گیرد، از فاصله بعد از پرانتزهای باز و قبل از بستن پرانتز استفاده نکنید و بعد از هر کاما از یک فاصله استفاده کنید. مثال ها: بین حاشیه نویسی و اعلان تابع نباید خطوط خالی وجود داشته باشد. مثال ها: از قوانین زیر برای اعلانهای enum استفاده کنید: از قوانین زیر برای اعلان ساختار استفاده کنید: بین موارد زیر فاصله قرار ندهید: مثال ها: بین موارد زیر فاصله قرار ندهید: مثال ها:PACKAGE-NAME
گفته میشود):
PACKAGE.MODULE[.SUBMODULE[.SUBMODULE[…]]]@VERSION
PACKAGE
بسته ای است که به ROOT-DIRECTORY
نگاشت می شود. به طور خاص، PACKAGE
عبارت است از:android.hardware
برای بسته های اصلی HIDL (نقشه برداری به hardware/interfaces
).vendor. VENDOR .hardware
برای بسته های فروشنده، که در آن VENDOR
به یک فروشنده SoC یا یک OEM/ODM (نقشه برداری به vendor/ VENDOR /interfaces
) اشاره دارد.MODULE [. SUBMODULE [. SUBMODULE […]]]@ VERSION
دقیقاً همان نام پوشه ها در ساختار توضیح داده شده در ساختار Directory هستند.snake_case
نوشته شوند.MAJOR.MINOR
import PACKAGE-NAME ;
import PACKAGE-NAME :: UDT ;
(یا اگر نوع وارد شده در همان بسته است، import UDT ;
import PACKAGE-NAME ::types;
PACKAGE-NAME
از قالب نامهای بسته پیروی میکند. بسته های فعلی types.hal
(اگر وجود داشته باشد) به طور خودکار وارد می شود (آن را به صراحت وارد نکنید).PACKAGE-NAME
حذف کنید. یک FQN نباید دارای فاصله باشد. نمونه ای از نام کاملا واجد شرایط:android.hardware.nfc@1.0::INfcClientCallback
android.hardware.nfc@1.0
، به رابط فوق با عنوان INfcClientCallback
مراجعه کنید. در غیر این صورت، فقط از نام کاملا واجد شرایط استفاده کنید.android.hardware
(از نام های کاملا واجد شرایط استفاده کنید).vendor. VENDOR
بسته های vendor. VENDOR
(از نام های کاملا واجد شرایط استفاده کنید).
import android.hardware.nfc@1.0::INfc;
import android.hardware.nfc@1.0::INfcClientCallback;
/* Importing the whole module. */
import vendor.barvendor.bar@3.1;
import vendor.foovendor.foo@2.2::IFooBar;
import vendor.foovendor.foo@2.2::IFooFoo;
import IBar;
import IFoo;
I
شروع شود و پس از آن یک نام UpperCamelCase
/ PascalCase
قرار گیرد. یک رابط با نام IFoo
باید در فایل IFoo.hal
تعریف شود. این فایل فقط می تواند شامل تعاریف برای رابط IFoo
باشد (رابط I NAME
باید در I NAME .hal
باشد).lowerCamelCase
استفاده کنید. مثال:
open(INfcClientCallback clientCallback) generates (int32_t retVal);
oneway pingAlive(IFooCallback cb);
lowerCamelCase
استفاده کنید. مثال:
struct FooReply {
vec<uint8_t> replyData;
}
typedef
s اشاره دارد. برای این نام ها، از UpperCamelCase
/ PascalCase
استفاده کنید. مثال ها:
enum NfcStatus : int32_t {
/*...*/
};
struct NfcData {
/*...*/
};
UPPER_CASE_WITH_UNDERSCORES
باشد. هنگام ارسال مقادیر enum به عنوان آرگومان های تابع و برگرداندن آنها به عنوان بازگشت تابع، از نوع enum واقعی (نه نوع عدد صحیح زیرین) استفاده کنید. مثال:
enum NfcStatus : int32_t {
HAL_NFC_STATUS_OK = 0,
HAL_NFC_STATUS_FAILED = 1,
HAL_NFC_STATUS_ERR_TRANSPORT = 2,
HAL_NFC_STATUS_ERR_CMD_TIMEOUT = 3,
HAL_NFC_STATUS_REFUSED = 4
};
PACKAGE-NAME::UDT[.UDT[.UDT[…]]:ENUM_VALUE_NAME
android.hardware.foo@1.0::IFoo.IFooInternal.FooEnum:ENUM_OK
//
، /* */
، و /** */
خوب هستند.
// This is a single line comment
/* This is also single line comment */
/** This is documentation comment */
/* */
استفاده کنید. در حالی که HIDL از //
برای نظرات پشتیبانی می کند، آنها دلسرد می شوند زیرا در خروجی تولید شده ظاهر نمی شوند./** */
استفاده کنید. اینها را می توان فقط برای نوع، روش، فیلد، و اعلان مقدار enum اعمال کرد. مثال:
/** Replied status */
enum TeleportStatus {
/** Object entirely teleported. */
OK = 0,
/** Methods return this if teleportation is not completed. */
ERROR_TELEPORT = 1,
/**
* Teleportation could not be completed due to an object
* obstructing the path.
*/
ERROR_OBJECT = 2,
...
}
/**
در یک خط جداگانه شروع کنید. در ابتدای هر خط از *
استفاده کنید. نظر را با */
در یک خط جداگانه پایان دهید و ستاره ها را تراز کنید. مثال:
/**
* My multi-line
* comment
*/
/*
شروع شود (یک ستاره)، از *
در ابتدای هر خط استفاده شود و */
در آخرین خط به تنهایی قرار گیرد (ستاره ها باید تراز شوند). مثال:
/*
* Copyright (C) 2017 The Android Open Source Project
* ...
*/
/*
* Changelog:
* ...
*/
development/docs/copyright-templates/c.txt
باشد. به یاد داشته باشید که سال را به روز کنید و از کامنت های چند خطی /* */
همانطور که در بالا توضیح داده شد استفاده کنید./* */
همانطور که در بالا توضیح داده شد استفاده کنید، خط خالی را بعد از تغییرات ثبت کنید، سپس با اعلام بسته همراه شوید.TODO
در تمام حروف و به دنبال آن یک دونقطه باشد. مثال:// TODO: remove this code before foo is checked in.
/** */
استفاده کنید. از //
برای رشته های مستند استفاده نکنید.
/**
* IFooController is the controller for foos.
*/
interface IFooController {
/**
* Opens the controller.
*
* @return status HAL_FOO_OK if successful.
*/
open() generates (FooStatus status);
/** Close the controller. */
close();
};
@param
و s @return
اضافه کنید:@param
اضافه شود. پس از آن باید نام پارامتر و سپس docstring قرار گیرد.@return
اضافه شود. پس از آن باید نام مقدار بازگشتی و سپس رشته docstring وجود داشته باشد.
/**
* Explain what foo does.
*
* @param arg1 explain what arg1 is
* @param arg2 explain what arg2 is
* @return ret1 explain what ret1 is
* @return ret2 explain what ret2 is
*/
foo(T arg1, T arg2) generates (S ret1, S ret2);
interface INfc {
close();
};
package PACKAGE-NAME;
package android.hardware.nfc@1.0;
generates
و مقادیر بازگشتی در صورت مناسب بودن باید در یک خط باشند. مثال:
interface IFoo {
/** ... */
easyMethod(int32_t data) generates (int32_t result);
};
generate
متمایز کنید تا به خواننده کمک کنید تا به سرعت پارامترها و مقادیر بازگشتی را ببیند. مثال:
interface IFoo {
suchALongMethodThatCannotFitInOneLine(int32_t theFirstVeryLongParameter,
int32_t anotherVeryLongParameter);
anEvenLongerMethodThatCannotFitInOneLine(int32_t theFirstLongParameter,
int32_t anotherVeryLongParameter)
generates (int32_t theFirstReturnValue,
int32_t anotherReturnValue);
superSuperSuperSuperSuperSuperSuperLongMethodThatYouWillHateToType(
int32_t theFirstVeryLongParameter, // 8 spaces
int32_t anotherVeryLongParameter
) generates (
int32_t theFirstReturnValue,
int32_t anotherReturnValue
);
/* method name is even shorter than 'generates' */
foobar(AReallyReallyLongType aReallyReallyLongParameter,
AReallyReallyLongType anotherReallyReallyLongParameter)
generates (ASuperLongType aSuperLongReturnValue, // 4 spaces
ASuperLongType anotherSuperLongReturnValue);
}
generates
در همان خط پرانتز بسته شدن قبلی است، از یک فاصله قبلی استفاده کنید. اگر generates
در همان خط پرانتز باز بعدی است، با فاصله دنبال کنید.
@annotate(keyword = value, keyword = {value, value, value})
@callflow(key = value)
@entry
@exit
/* Good */
@entry
@exit
/* Bad */
@entry @exit
@annotate(
keyword = value,
keyword = {
value,
value
},
keyword = value)
{
و بعد از هر کاما در داخل آرایه، خطوط شکسته را قرار دهید. پرانتز بسته را بلافاصله بعد از آخرین مقدار قرار دهید. اگر فقط یک مقدار وجود دارد، بریس ها را قرار ندهید.
/* Good */
@callflow(key = {"val", "val"})
/* Bad */
@callflow(key = { "val","val" })
/* Good */
@entry
foo();
/* Bad */
@entry
foo();
types.hal
قرار دهید.types.hal
قرار دهید.
struct MyStruct {
vec<uint8_t> data;
int32_t someInt;
}
/* Good */
int32_t[5] array;
/* Good */
int32_t[5][6] multiDimArray;
/* Bad */
int32_t [ 5 ] [ 6 ] array;
vec
و براکت زاویه باز.vec
است ).vec
است) .
/* Good */
vec<int32_t> array;
/* Good */
vec<vec<int32_t>> array;
/* Good */
vec< vec<int32_t> > array;
/* Bad */
vec < int32_t > array;
/* Bad */
vec < vec < int32_t > > array;