Kod stili kılavuzu

HIDL kod stili, Android çerçevesinde 4 boşluklu C++ koduna benzer girintiler ve büyük/küçük harf karışık dosya adları. Paket beyanları, içe aktarmalar ve docstring'ler bazı küçük değişikliklerle Java'dakilere benzer.

IFoo.hal ve types.hal için aşağıdaki örnekler HIDL kod stillerini gösterir ve her stille ilgili ayrıntılara hızlı bağlantılar sağlar (IFooClientCallback.hal, IBar.hal ve IBaz.hal yoksayıldı).

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

Adlandırma kuralları

İşlev adları, değişken adları ve dosya adları açıklayıcı olmalıdır; kaçınma ve aşırı kısaltma kullanma. Kısaltmaları kelime olarak değerlendirin (örneğin, bunun yerine INfc kullanın / INFC).

Dizin yapısı ve dosya adlandırma

Dizin yapısı şu şekilde görünmelidir:

  • ROOT-DIRECTORY
    • MODULE
      • SUBMODULE (isteğe bağlı, birden fazla olabilir) düzeyinde)
        • VERSION
          • Android.mk
          • IINTERFACE_1.hal
          • IINTERFACE_2.hal
          • IINTERFACE_N.hal
          • types.hal (isteğe bağlı)

Nerede:

  • ROOT-DIRECTORY:
    • Temel HIDL paketleri için hardware/interfaces.
    • Tedarikçi firma paketleri için vendor/VENDOR/interfaces, Burada VENDOR, bir SoC tedarikçisini veya OEM/ODM.
  • MODULE, aşağıdakileri içeren küçük bir kelime olmalıdır: alt sistem (örneğin, nfc). Birden fazla kelime gerekiyorsa iç içe yerleştirilmiş SUBMODULE. Birden fazla düzeyde iç içe yerleştirme.
  • VERSION ile aynı sürüm olmalıdır Sürümler bölümünde açıklandığı gibi (major.minor).
  • IINTERFACE_X, UpperCamelCase/PascalCase (örneğin, INfc) arayüz adlarında açıklandığı gibi.

Örnek:

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

Not: Tüm dosyalar yürütülebilir olmayan dosyalar içermelidir izinlerini kontrol edin (Git'te).

Paket adları

Paket adları aşağıdaki tam nitelikli adı kullanmalıdır (FQN) biçimindedir (PACKAGE-NAME olarak belirtilir):

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

Nerede:

  • PACKAGE, ROOT-DIRECTORY. Özellikle, PACKAGE:
    • Temel HIDL paketleri için android.hardware (şununla eşleme: hardware/interfaces) tıklayın.
    • Tedarikçi firma paketleri için vendor.VENDOR.hardware; burada VENDOR, bir SoC tedarikçisini veya OEM/ODM (eşleme) ile vendor/VENDOR/interfaces arasında).
  • MODULE[.SUBMODULE[.SUBMODULE[…]]]@VERSION. bölümünde açıklanan yapıdaki klasör adlarıyla tam olarak aynıdır. Dizin yapısı.
  • Paket adlarında küçük harf kullanılmalıdır. Metinler bir kelimeden uzunsa kelimeler alt modül olarak kullanılmalı veya snake_case dilinde yazılmalıdır.
  • Boşluklara izin verilmez.

FQN, paket bildirimlerinde her zaman kullanılır.

Sürümler

Sürümler aşağıdaki biçimde olmalıdır:

MAJOR.MINOR

Hem MAJOR hem de MINOR sürümü tek bir sürüm olmalıdır Tam sayı. HIDL semantik sürüm oluşturma kurallarını uygulayın.

İçe aktarmalar

İçe aktarma işlemi aşağıdaki üç biçimden birine sahiptir:

  • Tüm paketi içe aktarma işlemleri: import PACKAGE-NAME;
  • Kısmi içe aktarmalar: import PACKAGE-NAME::UDT; (veya içe aktarılan türü aynı pakette;import UDT;
  • Yalnızca türlerden içe aktarma işlemleri: import PACKAGE-NAME::types;

PACKAGE-NAME, şu biçime sahiptir: Paket adları. Mevcut paketin types.hal (varsa) otomatik olarak içe aktarılır (içe aktarmayın) açık bir şekilde belirtmelisiniz).

Tam nitelikli adlar (FQN'ler)

Kullanıcı tanımlı bir tür içe aktarma işlemi için tam nitelikli adları yalnızca gerektiğinde kullanın. İçe aktarma türü aynıysa PACKAGE-NAME değerini hariç tutun paketinden yararlanın. FQN boşluk içermemelidir. Tam nitelikli ad örneği:

android.hardware.nfc@1.0::INfcClientCallback

android.hardware.nfc@1.0 altındaki başka bir dosyada şuraya bakın: arayüzün üzerinde INfcClientCallback olarak görünür. Aksi halde yalnızca tam nitelikli ad.

İçe aktarmaları gruplandırma ve sıralama

Paket bildiriminden sonra (içe aktarma işlemlerinden önce) boş bir satır kullanın. Her içe aktarma tek bir satır kaplamalı ve girintili olmamalıdır. İçe aktarma işlemlerini şu sıra:

  1. Diğer android.hardware paketleri (tam nitelikli adlar kullanın).
  2. Diğer vendor.VENDOR paketleri (tam nitelikli adları).
    • Her tedarikçi bir grup olmalıdır.
    • Tedarikçileri alfabetik olarak sıralayın.
  3. Aynı paketteki diğer arayüzlerden içe aktarma işlemleri (basit adlar kullanın).

Gruplar arasında boş bir çizgi kullanın. Her grupta içe aktarmaları sıralayın emin olmanız gerekir. Örnek:

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;

Arayüz adları

Arayüz adları I ile başlamalı ve ardından UpperCamelCase/PascalCase ad. Adlandırılmış arayüz IFoo, IFoo.hal dosyasında tanımlanmalıdır. Bu dosya yalnızca IFoo arayüzüne (arayüz) ilişkin tanımları içerebilir INAME, INAME.hal içinde olmalıdır).

Fonksiyonlar

İşlev adları, bağımsız değişkenler ve dönüş değişkeni adları için lowerCamelCase Örnek:

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

Struct ve birleşim alan adları

struct veya union alan adları için lowerCamelCase kullanın. Örnek:

struct FooReply {
    vec<uint8_t> replyData;
}

Tür adları

Tür adları, struct veya union tanımlarını, enum türü tanımlarını ve typedef sn. Bu adlar için, UpperCamelCase/PascalCase Örnekler:

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

Enum değerleri

Enum değerleri UPPER_CASE_WITH_UNDERSCORES olmalıdır. Geçerken enum değerlerini işlev bağımsız değişkenleri olarak kullanma ve bunları işlev değeri olarak döndürme, gerçek enum türü (temel tam sayı türü değil). Örnek:

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

Not: Sıralama türünün temel türü iki nokta üst üste işaretinden sonra açıkça belirtilir. Derleyiciye bağlı olmadığından gerçek enum türü daha nettir.

Numaralandırma değerlerinin tam nitelikli adlarında iki nokta kullanılır. (enum türü adı ile enum değer adı) arasına:

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

Tam nitelikli adlarda boşluk olmamalıdır. Tam nitelikli yalnızca gerekli olduğunda ad verin ve gereksiz kısımları atlayın. Örnek:

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

Yorumlar

Tek satırlık bir yorum için, //, /* */ ve /** */ iyidir.

// This is a single line comment
/* This is also single line comment */
/** This is documentation comment */
  • Yorumlar için /* */ kullanın. HIDL yorumlar için // özelliğini destekler. oluşturulan çıktıda görünmedikleri için önerilmez.
  • Oluşturulan dokümanlar için /** */ kullanın. Bu düzenlemeler, yalnızca tür, yöntem, alan ve enum değer bildirimlerine izin verir. Örnek:
    /** 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,
        ...
    }
    
    .
  • Çok satırlı yorumlara /** ile ayrı bir satırda başlayın. Her satırın başında * kullanın. */ ile yorumu, yıldız işaretlerini hizalayarak ayrı bir satırda sonlandırın. Örnek:
    /**
     * My multi-line
     * comment
     */
    
    .
  • Lisanslama bildirimi ve değişiklik günlükleri, /* ile yeni bir satıra başlamalıdır (tek yıldız işareti), her satırın başında * kullanın ve */, son satıra tek başına gelecektir (yıldızlar aynı hizada olmalıdır). Örnek:
    /*
     * Copyright (C) 2017 The Android Open Source Project
     * ...
     */
    
    /*
     * Changelog:
     * ...
     */
    
    .

Dosya yorumları

Her dosyaya uygun lisans bildirimiyle başlayın. Temel HAL'ler için bu, Şu konumdaki AOSP Apache lisansı olmalıdır: development/docs/copyright-templates/c.txt. Yılı güncellemeyi ve /* */ stili çok satırlı yorumlar kullanmayı unutmayın değiştirebilirsiniz.

İsterseniz lisans bildiriminden sonra boş bir satır ekleyip bunu yapabilirsiniz. /* */ stilini kullan çok satırlı yorumlarda açıklandığı gibi, değişiklik günlüğüne girin, ardından paket bildirimini ekleyin.

TODO yorumları

Yapılacaklar listesinde, tamamı büyük harf içeren TODO dizesi ve ardından gelen dize iki nokta üst üste. Örnek:

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

TODO yorumlarına yalnızca geliştirme sırasında izin verilir; şunları yapması gerekir: yayınlanan arayüzlerde bulunmaması gerekir.

Arayüz ve işlev yorumları (docstrings)

Çok satırlı ve tek satırlı doküman dizeleri için /** */ kullanın. Kullanma docstring'ler için //.

Arayüzlere ilişkin belge dizeleri, arayüzü, tasarım gerekçesi, amacı vb. işlevine özeldir (paket düzeyindeki belgeler .

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

Her biri için @param ve @return eklemeniz gerekir parametre/döndürme değeri:

  • Her parametre için @param eklenmelidir. Değerin ardından parametrenin adı ve ardından docstring yazın.
  • Döndürülen her değer için @return eklenmelidir. Google öncesinde döndürülen değerin adı ve ardından docstring gelmelidir.

Örnek:

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

Biçimlendirme kuralları

Genel biçimlendirme kuralları şunları içerir:

  • Satır uzunluğu. Her metin satırı en fazla 100 sütun uzunluğunda.
  • Boşluklar. Satırların sonunda boşluk olmamalıdır; boş satırlar boşluk içermemelidir.
  • Alanlar ve sekmeler. Yalnızca boşluk kullanın.
  • Girinti boyutu. Engellemeler ve başlıklar için 4 boşluk kullanın. Satır sarmalama için 8 boşluk
  • Rota izleme. Not hariç değerleri için bir açık küme parantezi öncekiyle aynı satıra gider bir close küme parantezi ve aşağıdaki noktalı virgül şu şekilde işliyor: girin. Örnek:
    interface INfc {
        close();
    };
    
    .

Kargo beyanı

Paket beyanı, lisanstan sonra dosyanın en üst kısmında olmalıdır tüm satırı kaplamalı ve girintili olmamalıdır. Paketler belirtilen biçimi kullanın (ad biçimlendirmesi için bkz. Paket adları):

package PACKAGE-NAME;

Örnek:

package android.hardware.nfc@1.0;

İşlev bildirimleri

İşlev adı, parametreler, generates ve döndürülen değerler aynı çizgide olmalılar. Örnek:

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

Aynı satıra sığmazlarsa parametreleri yerleştirmeyi ve şunu döndürmeyi deneyin: değerlerini aynı girinti düzeyinde oluşturun ve generate ayırt edici uygulamanın yardımcı olması için Okuyucu, parametreler ve döndürülen değerleri hızlıca görür. Örnek:

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

Ek ayrıntılar:

  • Bir açık parantez, her zaman işlev adıyla aynı satırda bulunur.
  • İşlev adı ile açık parantez arasında boşluk olmamalıdır.
  • Parantezler ve parametreler arasında boşluk olmaması hariç, bunların arasındaki satır feed'leridir.
  • generates, önceki kapanışla aynı satırdaysa önce boşluk kullanın. generates değeri aynıysa satırından sonra bir boşluk bırakın.
  • Tüm parametreleri ve döndürülen değerleri (mümkünse) hizalayın.
  • Varsayılan girinti 4 boşluktur.
  • Sarmalanmış parametreler, önceki satırdaki ilk parametrelerle hizalanır. aksi takdirde 8 boşluk girintisi vardır.

Ek Açıklamalar

Ek açıklamalar için aşağıdaki biçimi kullanın:

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

Ek açıklamaları alfabetik olarak sıralayın ve eşittir işaretlerinin etrafında boşluk kullanın. Örnek:

@callflow(key = value)
@entry
@exit

Ek açıklamanın tüm satırı kapladığından emin olun. Örnekler:

/* Good */
@entry
@exit

/* Bad */
@entry @exit

Ek açıklamalar aynı satıra sığmıyorsa girintiyi 8 boşlukla girin. Örnek:

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

Değer dizisinin tamamı aynı satıra sığmıyorsa sonuna satır sonları koyun açık küme parantezleri { ve her virgülden sonra dizi içinde olmalıdır. Yer kapatma parantezi kullanabilirsiniz. Varsa küme parantezi koymayın tek bir değer kullanın.

Değer dizisinin tamamı aynı satıra sığabiliyorsa sonrasında boşluk kullanmayın küme parantezlerini açın ve kapatmadan önce küme parantezlerini açın ve her virgülden sonra bir boşluk kullanın. Örnekler:

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

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

Ek açıklamalar ile işlev arasında boş satırlar OLMAMALIDIR. beyanı. Örnekler:

/* Good */
@entry
foo();

/* Bad */
@entry

foo();

Sıralama bildirimleri

Enum bildirimleri için aşağıdaki kuralları kullanın:

  • Enum bildirimleri başka bir paketle paylaşılıyorsa bildirimleri yerleştirin. bir arayüz içine yerleştirmek yerine types.hal içinde kullanın.
  • İki nokta üst üste işaretinden önce ve sonra bir boşluk, temel türden sonra da boşluk kullanın işaretini kaldırın.
  • Son sıralama değerinde fazladan bir virgül olmayabilir.

Struct beyanları

struct bildirimleri için aşağıdaki kuralları kullanın:

  • struct beyanları başka bir paketle paylaşılıyorsa beyanları yerleştirin. bir arayüz içine yerleştirmek yerine types.hal içinde kullanın.
  • struct türü adından sonra, açık küme parantezinden önce boşluk kullanın.
  • Alan adlarını hizalayın (isteğe bağlı). Örnek:
    struct MyStruct {
        vec<uint8_t>   data;
        int32_t        someInt;
    }
    
    .

Dizi bildirimleri

Aşağıdakiler arasında boşluk bırakmayın:

  • Öğe türü ve açık köşeli parantez.
  • Köşeli parantez ve dizi boyutunu aç.
  • Dizi boyutu ve kapalı köşeli parantez.
  • Birden fazla köşeli parantezi ve bir sonraki açık köşeli ayracı kapatın boyutu bulunuyor.

Örnekler:

/* Good */
int32_t[5] array;

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

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

Vektörler

Aşağıdakiler arasında boşluk bırakmayın:

  • vec ve açılı ayracı aç.
  • Açılı ayracı ve öğe türünü açın (İstisna: öğe türü aynı zamanda bir vec) bulabilirsiniz.
  • Öğe türü ve açılı ayracı kapatma (İstisna: öğe türü aynı zamanda bir vec).

Örnekler:

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