Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Panduan Gaya Kode

Gaya kode HIDL menyerupai kode C ++ dalam kerangka kerja Android, dengan indentasi 4 spasi dan nama file kasus campuran. Deklarasi paket, impor, dan docstrings mirip dengan yang ada di Java, dengan sedikit modifikasi.

Contoh IFoo.hal dan types.hal mengilustrasikan gaya kode HIDL dan menyediakan tautan cepat ke detail pada setiap gaya ( IFooClientCallback.hal , IBar.hal , dan IBaz.hal telah dihilangkan).

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;
};

Konvensi penamaan

Nama fungsi, nama variabel, dan nama file harus deskriptif; hindari singkatan yang berlebihan. Perlakukan akronim sebagai kata-kata (misalnya, gunakan INfc daripada INFC ).

Struktur direktori dan penamaan file

Struktur direktori akan muncul sebagai berikut:

  • ROOT-DIRECTORY
    • MODULE
      • SUBMODULE (opsional, bisa lebih dari satu level)
        • VERSION
          • Android.mk
          • I INTERFACE_1 .hal
          • I INTERFACE_2 .hal
          • I INTERFACE_N .hal
          • types.hal (opsional)

Dimana:

  • ROOT-DIRECTORY adalah:
    • hardware/interfaces untuk paket inti HIDL.
    • vendor/ VENDOR /interfaces untuk paket vendor, di mana VENDOR mengacu pada vendor SoC atau OEM / ODM.
  • MODULE harus berupa satu huruf kecil yang menggambarkan subsistem (mis. nfc ). Jika lebih dari satu kata diperlukan, gunakan SUBMODULE bertingkat. Mungkin ada lebih dari satu tingkat bersarang.
  • VERSION harus versi yang sama persis (mayor.minor) seperti yang dijelaskan dalam Versi .
  • I INTERFACE_X harus menjadi nama antarmuka dengan UpperCamelCase / PascalCase (misalnya INfc ) seperti yang dijelaskan dalam nama Antarmuka .

Contoh:

  • hardware/interfaces
    • nfc
      • 1.0
        • Android.mk
        • INfc.hal
        • INfcClientCallback.hal
        • types.hal

Catatan: Semua file harus memiliki izin yang tidak dapat dijalankan (di Git).

Nama paket

Nama paket harus menggunakan format nama berkualifikasi lengkap (FQN) berikut (disebut sebagai PACKAGE-NAME ):

PACKAGE.MODULE[.SUBMODULE[.SUBMODULE[…]]]@VERSION

Dimana:

  • PACKAGE adalah paket yang memetakan ke ROOT-DIRECTORY . Secara khusus, PACKAGE adalah:
    • android.hardware untuk paket inti HIDL (pemetaan ke hardware/interfaces ).
    • vendor. VENDOR .hardware untuk paket vendor, di mana VENDOR merujuk ke vendor SoC atau OEM / ODM (pemetaan ke vendor/ VENDOR /interfaces ).
  • MODULE [. SUBMODULE [. SUBMODULE […]]]@ VERSION adalah nama folder yang sama persis dalam struktur yang dijelaskan dalam struktur Direktori .
  • Nama paket harus huruf kecil. Jika panjangnya lebih dari satu kata, kata tersebut harus digunakan sebagai submodul atau ditulis dalam snake_case .
  • Tidak ada spasi yang diperbolehkan.

FQN selalu digunakan dalam deklarasi paket.

Versi

Versi harus memiliki format berikut:

MAJOR.MINOR

Baik versi MAJOR dan MINOR harus berupa bilangan bulat tunggal. HIDL menggunakan aturan pembuatan versi semantik .

Impor

Impor memiliki salah satu dari tiga format berikut:

  • Impor seluruh paket: import PACKAGE-NAME ;
  • Impor parsial: import PACKAGE-NAME :: UDT ; (atau, jika jenis yang diimpor ada dalam paket yang sama, import UDT ;
  • Impor khusus jenis: import PACKAGE-NAME ::types;

PACKAGE-NAME mengikuti format dalam nama Paket . types.hal paket saat ini (jika ada) secara otomatis diimpor (jangan impor secara eksplisit).

Nama yang sepenuhnya memenuhi syarat (FQN)

Gunakan nama yang sepenuhnya memenuhi syarat untuk jenis impor yang ditentukan pengguna hanya jika diperlukan. Hilangkan PACKAGE-NAME jika jenis impor ada dalam paket yang sama. FQN tidak boleh mengandung spasi. Contoh nama yang sepenuhnya memenuhi syarat:

android.hardware.nfc@1.0::INfcClientCallback

Di file lain di bawah android.hardware.nfc@1.0 , lihat antarmuka di atas sebagai INfcClientCallback . Jika tidak, gunakan hanya nama yang sepenuhnya memenuhi syarat.

Pengelompokan dan pemesanan impor

Gunakan baris kosong setelah deklarasi paket (sebelum impor). Setiap impor harus menempati satu baris dan tidak boleh diberi indentasi. Kelompokkan impor dengan urutan sebagai berikut:

  1. Paket android.hardware lainnya (gunakan nama yang sepenuhnya memenuhi syarat).
  2. vendor. VENDOR lain vendor. VENDOR Paket vendor. VENDOR (gunakan nama yang sepenuhnya memenuhi syarat).
    • Setiap vendor harus menjadi grup.
    • Pesan vendor menurut abjad.
  3. Impor dari antarmuka lain dalam paket yang sama (gunakan nama sederhana).

Gunakan garis kosong antar grup. Di dalam setiap grup, urutkan impor menurut abjad. Contoh:

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;

Nama antarmuka

Nama antarmuka harus dimulai dengan I , diikuti dengan nama UpperCamelCase / PascalCase . Antarmuka dengan nama IFoo harus ditentukan dalam file IFoo.hal . File ini dapat berisi definisi hanya untuk antarmuka IFoo (antarmuka I NAME harus dalam I NAME .hal ).

Fungsi

Untuk nama fungsi, argumen, dan nama variabel kembalian, gunakan lowerCamelCase . Contoh:

open(INfcClientCallback clientCallback) generates (int32_t retVal);
oneway pingAlive(IFooCallback cb);

Nama bidang struktur / serikat

Untuk nama field struct / union, gunakan lowerCamelCase . Contoh:

struct FooReply {
    vec<uint8_t> replyData;
}

Ketik nama

Nama tipe mengacu pada definisi struct / union, definisi tipe enum, dan typedef s. Untuk nama ini, gunakan UpperCamelCase / PascalCase . Contoh:

enum NfcStatus : int32_t {
    /*...*/
};
struct NfcData {
    /*...*/
};

Nilai enum

Nilai enum harus UPPER_CASE_WITH_UNDERSCORES . Saat meneruskan nilai enum sebagai argumen fungsi dan mengembalikannya sebagai pengembalian fungsi, gunakan tipe enum aktual (bukan tipe integer yang mendasari). Contoh:

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
};

Catatan: Tipe dasar dari tipe enum secara eksplisit dideklarasikan setelah titik dua. Karena tidak bergantung pada compiler, penggunaan tipe enum sebenarnya lebih jelas.

Untuk nama yang sepenuhnya memenuhi syarat untuk nilai enum, titik dua digunakan antara nama jenis enum dan nama nilai enum:

PACKAGE-NAME::UDT[.UDT[.UDT[…]]:ENUM_VALUE_NAME

Tidak boleh ada spasi di dalam nama yang sepenuhnya memenuhi syarat. Gunakan nama yang sepenuhnya memenuhi syarat hanya jika perlu dan hilangkan bagian yang tidak perlu. Contoh:

android.hardware.foo@1.0::IFoo.IFooInternal.FooEnum:ENUM_OK

Komentar

Untuk komentar satu baris, // , /* */ , dan /** */ tidak masalah.

// This is a single line comment
/* This is also single line comment */
/** This is documentation comment */
  • Gunakan /* */ untuk komentar. Meskipun HIDL mendukung // untuk komentar, mereka tidak disarankan karena tidak muncul dalam keluaran yang dihasilkan.
  • Gunakan /** */ untuk dokumentasi yang dihasilkan. Ini hanya dapat diterapkan untuk jenis, metode, bidang, dan deklarasi nilai enum. Contoh:
    /** 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,
        ...
    }
    
  • Mulai komentar multibaris dengan /** pada baris terpisah. Gunakan * di awal setiap baris. Akhiri komentar dengan */ pada baris terpisah, sejajarkan tanda bintang. Contoh:
    /**
     * My multi-line
     * comment
     */
    
  • Pemberitahuan lisensi dan log perubahan harus memulai baris baru dengan /* (tanda bintang tunggal), gunakan * di awal setiap baris, dan tempatkan */ di baris terakhir dengan sendirinya (tanda bintang harus sejajar). Contoh:
    /*
     * Copyright (C) 2017 The Android Open Source Project
     * ...
     */
    
    /*
     * Changelog:
     * ...
     */
    

Kirimkan komentar

Mulai setiap file dengan pemberitahuan lisensi yang sesuai. Untuk HAL inti, ini harus menjadi lisensi AOSP Apache dalam development/docs/copyright-templates/c.txt . Ingatlah untuk memperbarui tahun dan gunakan /* */ gaya komentar beberapa baris seperti yang dijelaskan di atas.

Anda secara opsional dapat menempatkan baris kosong setelah pemberitahuan lisensi, diikuti dengan log perubahan / informasi versi. Gunakan komentar multi-baris /* */ style seperti yang dijelaskan di atas, letakkan baris kosong setelah changelog, lalu ikuti dengan deklarasi paket.

Komentar TODO

TODO harus menyertakan string TODO dalam huruf besar semua diikuti dengan titik dua. Contoh:

// TODO: remove this code before foo is checked in.

Komentar TODO hanya diperbolehkan selama pengembangan; mereka tidak boleh ada di antarmuka yang diterbitkan.

Antarmuka / Fungsi komentar (docstrings)

Gunakan /** */ untuk dokumen multi-baris dan satu baris. Jangan gunakan // untuk docstrings.

Docstring untuk antarmuka harus menjelaskan mekanisme umum dari antarmuka, alasan desain, tujuan, dll. Docstring untuk fungsi harus spesifik untuk fungsi tersebut (dokumentasi tingkat paket masuk dalam file README di direktori paket).

/**
 * 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();
};

Anda harus menambahkan @param s dan @return s untuk setiap parameter / nilai kembali:

  • @param harus ditambahkan untuk setiap parameter. Ini harus diikuti dengan nama parameter kemudian docstring.
  • @return harus ditambahkan untuk setiap nilai kembali. Ini harus diikuti dengan nama nilai yang dikembalikan kemudian docstring tersebut.

Contoh:

/**
 * 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);

Pemformatan

Aturan pemformatan umum meliputi:

  • Panjang garis . Setiap baris teks harus terdiri dari maksimal 100 kolom.
  • Spasi putih . Tidak ada spasi kosong di baris; baris kosong tidak boleh mengandung spasi.
  • Spasi vs. tab . Gunakan hanya spasi.
  • Ukuran indentasi . Gunakan 4 spasi untuk balok dan 8 spasi untuk membungkus garis
  • Penguat . Kecuali untuk nilai anotasi , kurung kurawal buka di baris yang sama seperti kode sebelumnya tetapi kurung kurawal tutup dan titik koma berikutnya menempati seluruh baris. Contoh:
    interface INfc {
        close();
    };
    

Deklarasi paket

Deklarasi paket harus berada di bagian atas file setelah pemberitahuan lisensi, harus memenuhi seluruh baris, dan tidak boleh menjorok ke dalam. Paket dideklarasikan menggunakan format berikut (untuk pemformatan nama, lihat Nama paket ):

package PACKAGE-NAME;

Contoh:

package android.hardware.nfc@1.0;

Deklarasi fungsi

Fungsi nama, parameter, generates , dan kembali nilai-nilai harus pada baris yang sama jika mereka cocok. Contoh:

interface IFoo {
    /** ... */
    easyMethod(int32_t data) generates (int32_t result);
};

Jika mereka tidak cocok pada baris yang sama, mencoba untuk menempatkan parameter dan kembali nilai-nilai di tingkat indent yang sama dan membedakan generate untuk membantu pembaca dengan cepat melihat parameter dan kembali nilai-nilai. Contoh:

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);
}

Detil tambahan:

  • Tanda kurung buka selalu di baris yang sama dengan nama fungsi.
  • Tidak ada spasi antara nama fungsi dan tanda kurung buka.
  • Tidak ada spasi di antara tanda kurung dan parameter kecuali jika ada umpan baris di antara keduanya.
  • Jika generates adalah pada baris yang sama seperti penutupan kurung sebelumnya, menggunakan ruang sebelumnya. Jika generates berada di baris yang sama dengan tanda kurung buka berikutnya, ikuti dengan spasi.
  • Sejajarkan semua parameter dan kembalikan nilai (jika memungkinkan).
  • Indentasi default adalah 4 spasi.
  • Parameter yang dibungkus disejajarkan dengan parameter pertama pada baris sebelumnya, jika tidak, mereka memiliki indentasi 8 spasi.

Anotasi

Gunakan format berikut untuk anotasi:

@annotate(keyword = value, keyword = {value, value, value})

Urutkan anotasi dalam urutan abjad, dan gunakan spasi di sekitar tanda yang sama. Contoh:

@callflow(key = value)
@entry
@exit

Pastikan anotasi memenuhi seluruh baris. Contoh:

/* Good */
@entry
@exit

/* Bad */
@entry @exit

Jika anotasi tidak bisa muat pada baris yang sama, indentasi dengan 8 spasi. Contoh:

@annotate(
        keyword = value,
        keyword = {
                value,
                value
        },
        keyword = value)

Jika seluruh larik nilai tidak bisa muat di baris yang sama, letakkan jeda baris setelah kurung kurawal { dan setelah setiap koma di dalam larik. Tempatkan tanda kurung tutup tepat setelah nilai terakhir. Jangan memasang kawat gigi jika hanya ada satu nilai.

Jika seluruh larik nilai bisa muat dalam baris yang sama, jangan gunakan spasi setelah kurung kurawal buka dan sebelum tanda kurung kurawal tutup dan gunakan satu spasi setelah setiap koma. Contoh:

/* Good */
@callflow(key = {"val", "val"})

/* Bad */
@callflow(key = { "val","val" })

TIDAK boleh ada baris kosong antara anotasi dan deklarasi fungsi. Contoh:

/* Good */
@entry
foo();

/* Bad */
@entry

foo();

Deklarasi enum

Gunakan aturan berikut untuk deklarasi enum:

  • Jika deklarasi enum dibagikan dengan paket lain, letakkan deklarasi di types.hal daripada menyematkannya di dalam antarmuka.
  • Gunakan spasi sebelum dan sesudah titik dua, dan spasi setelah jenis yang mendasari sebelum kurung kurawal buka.
  • Nilai enum terakhir mungkin atau mungkin tidak memiliki koma tambahan.

Deklarasi struktur

Gunakan aturan berikut untuk deklarasi struct:

  • Jika deklarasi struct dibagikan dengan paket lain, letakkan deklarasi di types.hal daripada menyematkannya di dalam antarmuka.
  • Gunakan spasi setelah nama tipe struct sebelum kurung kurawal buka.
  • Sejajarkan nama bidang (opsional). Contoh:
    struct MyStruct {
        vec<uint8_t>   data;
        int32_t        someInt;
    }
    

Deklarasi array

Jangan beri spasi di antara berikut ini:

  • Jenis elemen dan braket persegi terbuka.
  • Buka braket persegi dan ukuran larik.
  • Ukuran array dan braket persegi dekat.
  • Braket persegi tutup dan braket persegi terbuka berikutnya, jika ada lebih dari satu dimensi.

Contoh:

/* Good */
int32_t[5] array;

/* Good */
int32_t[5][6] multiDimArray;

/* Bad */
int32_t [ 5 ] [ 6 ] array;

Vektor

Jangan beri spasi di antara berikut ini:

  • vec dan braket sudut terbuka.
  • Braket sudut terbuka dan tipe elemen ( Pengecualian: tipe elemen juga vec ).
  • Jenis elemen dan braket sudut dekat ( Pengecualian: tipe elemen juga vec ) .

Contoh:

/* 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;