Google berkomitmen untuk memajukan ekuitas ras untuk komunitas kulit hitam. Lihat bagaimana.
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Panduan Gaya Kode

Gaya kode HIDL menyerupai kode C ++ dalam kerangka Android, dengan indentasi 4-ruang dan nama file campuran. Deklarasi paket, impor, dan dokumen mirip dengan yang ada di Jawa, dengan sedikit modifikasi.

Contoh-contoh berikut untuk IFoo.hal dan types.hal menggambarkan gaya kode HIDL dan memberikan 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 (mis., Gunakan INfc sebagai ganti 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 merujuk ke vendor SoC atau OEM / ODM.
  • MODULE harus berupa satu kata kecil yang menggambarkan subsistem (mis. nfc ). Jika diperlukan lebih dari satu kata, gunakan SUBMODULE bersarang. Mungkin ada lebih dari satu tingkat sarang.
  • VERSION harus versi yang sama persis (major.minor) seperti yang dijelaskan dalam Versi .
  • I INTERFACE_X harus berupa 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 dieksekusi (dalam Git).

Nama paket

Nama paket harus menggunakan format nama yang memenuhi syarat (FQN) berikut ini (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 persis sama dalam struktur yang dijelaskan dalam struktur Direktori .
  • Nama paket harus huruf kecil. Jika panjangnya lebih dari satu kata, kata-kata tersebut harus digunakan sebagai submodul atau ditulis dalam snake_case .
  • Tidak ada spasi yang diizinkan.

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 versi semantik .

Impor

Impor memiliki salah satu dari tiga format berikut:

  • Impor seluruh paket: import PACKAGE-NAME ;
  • Impor sebagian: import PACKAGE-NAME :: UDT ; (atau, jika jenis yang diimpor dalam paket yang sama, import UDT ;
  • Impor jenis saja: 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 (FQNs)

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

android.hardware.nfc@1.0::INfcClientCallback

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

Mengelompokkan dan memesan impor

Gunakan baris kosong setelah deklarasi paket (sebelum impor). Setiap impor harus menempati satu baris dan tidak boleh di-indentasi. Impor grup dalam urutan berikut:

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

Gunakan garis kosong di antara grup. Di dalam setiap grup, urutkan impor berdasarkan 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 oleh nama UpperCamelCase / PascalCase . Antarmuka dengan nama IFoo harus didefinisikan 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 mengembalikan nama variabel, gunakan lowerCamelCase . Contoh:

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

Nama bidang Struct / union

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

struct FooReply {
    vec<uint8_t> replyData;
}

Ketikkan nama

Tipe nama merujuk pada definisi struct / union, definisi tipe enum, dan typedef . Untuk nama ini, gunakan UpperCamelCase / PascalCase . Contoh:

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

Nilai enum

Nilai enum harus UPPER_CASE_WITH_UNDERSCORES . Saat melewatkan nilai enum sebagai argumen fungsi dan mengembalikannya sebagai fungsi, gunakan tipe enum yang sebenarnya (bukan tipe integer yang mendasarinya). 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 yang mendasari tipe enum secara eksplisit dinyatakan setelah titik dua. Karena tidak bergantung pada kompiler, menggunakan tipe enum yang sebenarnya lebih jelas.

Untuk nama yang sepenuhnya memenuhi syarat untuk nilai enum, tanda 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 bila perlu dan hilangkan bagian yang tidak perlu. Contoh:

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

Komentar

Untuk komentar satu baris, // , /* */ , dan /** */ baik-baik saja.

// This is a single line comment
/* This is also single line comment */
/** This is documentation comment */
  • Gunakan /* */ untuk komentar. Sementara HIDL mendukung // untuk komentar, mereka tidak disarankan karena tidak muncul dalam output yang dihasilkan.
  • Gunakan /** */ untuk dokumentasi yang dihasilkan. Ini dapat diterapkan hanya untuk mengetik, 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 multi-baris dengan /** pada baris terpisah. Gunakan * di awal setiap baris. Akhiri komentar dengan */ pada baris terpisah, sejajarkan tanda bintang. Contoh:
    /**
     * My multi-line
     * comment
     */
    
  • Pemberitahuan perizinan dan changelog harus memulai baris baru dengan /* (tanda bintang tunggal), gunakan * di awal setiap baris, dan letakkan */ di baris terakhir semuanya sendiri (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 haruslah lisensi AOSP Apache dalam development/docs/copyright-templates/c.txt . Ingatlah untuk memperbarui tahun dan gunakan komentar multi-baris /* */ style seperti dijelaskan di atas.

Anda dapat menempatkan baris kosong setelah pemberitahuan lisensi, diikuti oleh changelog / informasi versi. Gunakan komentar multi-baris /* */ style seperti dijelaskan di atas, tempatkan baris kosong setelah changelog, kemudian ikuti dengan deklarasi paket.

Komentar TODO

TODO harus menyertakan string TODO dalam semua topi diikuti oleh titik dua. Contoh:

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

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

Komentar Antarmuka / Fungsi (docstrings)

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

Dokumen untuk antarmuka harus menggambarkan mekanisme umum antarmuka, alasan desain, tujuan, dll. Dokumen untuk fungsi harus spesifik untuk fungsi tersebut (dokumentasi tingkat paket masuk dalam file README dalam 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 pengembalian:

  • @param harus ditambahkan untuk setiap parameter. Itu harus diikuti oleh nama parameter kemudian docstring.
  • @return return harus ditambahkan untuk setiap nilai pengembalian. Itu harus diikuti dengan nama nilai balik lalu docstring.

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

Memformat

Aturan pemformatan umum meliputi:

  • Panjang garis . Setiap baris teks paling panjang 100 kolom.
  • Ruang putih . Tidak ada spasi spasi pada garis; baris kosong tidak boleh berisi spasi putih.
  • Spasi vs. tab . Gunakan hanya spasi.
  • Ukuran indentasi Gunakan 4 spasi untuk blok dan 8 spasi untuk pembungkus baris
  • Menguatkan . Kecuali untuk nilai anotasi , kurung buka berjalan pada baris yang sama dengan kode sebelumnya tetapi kurung dekat dan titik koma berikut menempati seluruh baris. Contoh:
    interface INfc {
        close();
    };
    

Deklarasi paket

Deklarasi paket harus di bagian atas file setelah pemberitahuan lisensi, harus menempati seluruh baris, dan tidak boleh diindentasi. Paket dinyatakan menggunakan format berikut (untuk pemformatan nama, lihat Nama paket ):

package PACKAGE-NAME ;

Contoh:

package android.hardware.nfc@1.0;

Deklarasi fungsi

Nama fungsi, parameter, generates , dan nilai kembali harus pada baris yang sama jika sesuai. Contoh:

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

Jika tidak pas pada baris yang sama, cobalah untuk meletakkan parameter dan mengembalikan nilai di tingkat indentasi yang sama dan membedakan generate untuk membantu pembaca dengan cepat melihat parameter dan mengembalikan 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 terbuka selalu pada baris yang sama dengan nama fungsi.
  • Tidak ada spasi antara nama fungsi dan tanda kurung terbuka.
  • Tidak ada spasi di antara tanda kurung dan parameter kecuali ketika ada umpan baris di antara mereka.
  • Jika generates berada pada baris yang sama dengan tanda kurung tutup sebelumnya, gunakan ruang sebelumnya. Jika generates berada pada baris yang sama dengan tanda kurung buka berikutnya, ikuti dengan spasi.
  • Sejajarkan semua parameter dan kembalikan nilai (jika mungkin).
  • Indentasi default adalah 4 spasi.
  • Parameter yang dibungkus selaras dengan parameter pertama pada baris sebelumnya, jika tidak, mereka memiliki indentasi 8-ruang.

Anotasi

Gunakan format berikut untuk penjelasan:

@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 menempati seluruh baris. Contoh:

/* Good */
@entry
@exit

/* Bad */
@entry @exit

Jika anotasi tidak dapat masuk pada baris yang sama, indentasi dengan 8 spasi. Contoh:

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

Jika seluruh array nilai tidak dapat masuk dalam baris yang sama, letakkan putus baris setelah kurung buka { dan setelah setiap koma di dalam array. Tempatkan tanda kurung tutup segera setelah nilai terakhir. Jangan meletakkan kawat gigi jika hanya ada satu nilai.

Jika seluruh array nilai dapat masuk dalam baris yang sama, jangan gunakan spasi setelah kawat gigi terbuka dan sebelum menutup kawat gigi dan gunakan satu spasi setelah setiap koma. Contoh:

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

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

Tidak boleh ada garis kosong antara anotasi dan deklarasi fungsi. Contoh:

/* Good */
@entry
foo();

/* Bad */
@entry

foo();

Enum deklarasi

Gunakan aturan berikut untuk deklarasi enum:

  • Jika enum deklarasi dibagikan dengan paket lain, masukkan deklarasi dalam types.hal daripada menanamkan di dalam antarmuka.
  • Gunakan spasi sebelum dan sesudah usus besar, dan spasi setelah tipe yang mendasari sebelum kurung terbuka.
  • Nilai enum terakhir mungkin atau mungkin tidak memiliki koma tambahan.

Deklarasi Struct

Gunakan aturan berikut untuk deklarasi struct:

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

Deklarasi array

Jangan menempatkan spasi di antara yang berikut:

  • Jenis elemen dan braket kotak terbuka.
  • Buka braket persegi dan ukuran larik.
  • Ukuran array dan tutup braket kotak.
  • Tutup braket kotak dan braket kotak 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 menempatkan spasi di antara yang berikut:

  • vec dan braket sudut terbuka.
  • Braket sudut terbuka dan tipe elemen ( Pengecualian: tipe elemen juga vec ).
  • Tipe elemen dan bracket 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;