You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
8.2 KiB
208 lines
8.2 KiB
7 months ago
|
# Gabeldorsche Style Guide
|
||
|
|
||
|
[TOC]
|
||
|
|
||
|
## Base
|
||
|
|
||
|
In general, when not mentioned in this document, developers should follow the
|
||
|
Google C++ and Google Java style guide as much as possible.
|
||
|
|
||
|
### Google C++ Style Guide
|
||
|
|
||
|
C++ Style Guide: https://google.github.io/styleguide/cppguide.html
|
||
|
|
||
|
### Android and Google Java Style Guide
|
||
|
|
||
|
1. Android Java Style Guide:
|
||
|
https://source.android.com/setup/contribute/code-style
|
||
|
|
||
|
2. when not covered by (1), see External Java Style Guide:
|
||
|
https://google.github.io/styleguide/javaguide.html
|
||
|
|
||
|
line length limit is 120 characters for C++ and Java
|
||
|
|
||
|
### Python Style Guide
|
||
|
|
||
|
The GD stack uses the Google Python Style Guide:
|
||
|
|
||
|
* http://google.github.io/styleguide/pyguide.html
|
||
|
|
||
|
with the following modifications as shown in the
|
||
|
[.style.yapf](https://android.googlesource.com/platform/system/bt/+/refs/heads/master/.style.yapf) definition:
|
||
|
|
||
|
```yapf
|
||
|
based_on_style: google
|
||
|
indent_width: 4
|
||
|
column_limit: 120
|
||
|
```
|
||
|
|
||
|
## Build files
|
||
|
|
||
|
* One build target for the entire stack in system/bt (i.e. one cc_library())
|
||
|
* If only part of the stack needs to be compiled, configure it using the
|
||
|
“target” configuration in Android.bp
|
||
|
* One build target for all unit tests (i.e. one cc_test)
|
||
|
* When needed, filgroup() can be created in Android.bp in sub-directories. The
|
||
|
main build target should use these filegroups() to build the main output
|
||
|
library.
|
||
|
* All targets must have host_supported == true unless it is dependent on the
|
||
|
OS
|
||
|
* If the stack needs to be compiled using other build system, then the build
|
||
|
files should also live in system/bt
|
||
|
|
||
|
## Namespace and include
|
||
|
|
||
|
* Namespace must follow directory names
|
||
|
* Top level namespace for internal code is “bluetooth”
|
||
|
* Top level namespace for externally visible code is “android::bluetooth”
|
||
|
* Include path must be relative to the root directory of the stack. Normally
|
||
|
it is system/bt, for GD refactor code, it is system/bt/gd
|
||
|
|
||
|
## Multiple implementations of the same header
|
||
|
|
||
|
Since GD interact with many lower level components that are platform dependent,
|
||
|
frequently there is need to implement the same header multiple times for
|
||
|
different platform or hardware. When doing this:
|
||
|
|
||
|
* Avoid #define macros as much as possible. Instead put code into different
|
||
|
source files and selectively compile them for different targets.
|
||
|
* Convention of operating system used:
|
||
|
* android/
|
||
|
* All Android devices that use HIDL
|
||
|
* linux/
|
||
|
* All non-Android linux devices
|
||
|
* linux_generic/
|
||
|
* Android and non-Android linux devices
|
||
|
|
||
|
## Directory structure
|
||
|
|
||
|
Root directory under Android tree:
|
||
|
[**system/bt/gd/**](https://android.googlesource.com/platform/system/bt/+/refs/heads/master/gd/)
|
||
|
|
||
|
* Directory structure should be as flat as possible
|
||
|
* Each file should contain at most one class
|
||
|
* Header, source code, and unit test should live in the same directory with
|
||
|
the following naming guideline:
|
||
|
* Source: bb.cc
|
||
|
* Header: bb.h
|
||
|
* Test: bb_test.cc
|
||
|
* Each profile should have its own directory and module
|
||
|
* Source and sink, server and client profiles should live in two sub folders
|
||
|
of the same common directory where common code can be stored. However,
|
||
|
source and sink must have separate modules
|
||
|
* Module file is also the external API header
|
||
|
* Prefer underscore over dashes
|
||
|
|
||
|
### Example: utility library with OS dependent implementation
|
||
|
|
||
|
* os/: OS dependent classes such as Alarm, Thread, Handler
|
||
|
* Android.bp: Build file that defines file groups that would include
|
||
|
different source files based on compile time target
|
||
|
* alarm.h: common header for alarm
|
||
|
* linux_generic/: Implementations for generic Linux OS
|
||
|
* alarm.cc: Linux generic implementation of alarm.h using timer_fd
|
||
|
* alarm_test.cc: unit test for alarm.h
|
||
|
* fuzz/: library needed for fuzz tests in the os/ library
|
||
|
|
||
|
### Example: module with hardware dependent implementation
|
||
|
|
||
|
* hal/: Hardware abstraction layer such as HCI interfaces, Audio interfaces
|
||
|
* Android.bp: Build file that defines file groups that would include
|
||
|
different source files based on compile time target
|
||
|
* hci_hal.h: common library header
|
||
|
* hci_hal_android_hidl.cc: implementation of hci_hal.h using Android HIDL
|
||
|
* hci_hal_android_hidl_test.cc: unit tests for the Android HIDL
|
||
|
implementation
|
||
|
* hci_hal_host.cc: implementation of hci_hal.h using root-canal
|
||
|
emulator or linux Bluetooth HCI socket
|
||
|
* hci_hal_host_test.cc: unit tests for the socket based HAL (root-canal)
|
||
|
emulator implementation
|
||
|
* facade.proto: gRPC automation interface definition for this layer
|
||
|
* facade.h/cc: an implementation of the above gRPC interface for the GD
|
||
|
stack
|
||
|
* cert/: certification tests for this module
|
||
|
* fuzz/: library needed for fuzz tests in the hal/ module
|
||
|
|
||
|
### Example: similar protocol with the same base
|
||
|
|
||
|
* l2cap/: L2CAP layer, splitted among classic and LE
|
||
|
* classic/: Classic L2CAP module
|
||
|
* cert/: certification tests for this module
|
||
|
* internal/: internal code to be used only in classic
|
||
|
* Source code and headers being exported to other modules
|
||
|
* le/: LE L2CAP module
|
||
|
* cert/: certification tests for this module
|
||
|
* internal/: internal code to be used only in classic
|
||
|
* Source code and headers being exported to other modules
|
||
|
* internal/: L2CAP internal code that should not be used by sources
|
||
|
outside L2CAP
|
||
|
* data_pipeline_manager.h
|
||
|
* data_pipeline_manager.cc
|
||
|
* data_pipeline_manager_mock.h: Mock of this class, used in unit tests
|
||
|
* dynamic_channel_allocator.h
|
||
|
* dynamic_channel_allocator.cc
|
||
|
* dynamic_channel_allocator_test.cc: GTest unit test of this class
|
||
|
* dynamic_channel_allocator_fuzz_test.cc: Fuzz test of this class
|
||
|
* *.h/.cc: Common headers and sources that is exposed to other modules
|
||
|
|
||
|
### Example: protocol or profiles with client and server side implementations
|
||
|
|
||
|
* a2dp/: A2DP profile
|
||
|
* sink/: A2DP sink module (e.g. headset)
|
||
|
* source/: A2DP source module (e.g. phone)
|
||
|
* avrcp/
|
||
|
* controller/: AVRCP peripheral module (e.g. carkit)
|
||
|
* target/: AVRCP target module (e.g. Phone)
|
||
|
* hfp/
|
||
|
* hf/: Handsfree device (e.g. headset)
|
||
|
* ag/: Audio gateway (e.g. phone)
|
||
|
|
||
|
## External libraries
|
||
|
|
||
|
To maintain high portability, we are trying to stick with C++ STL as much as
|
||
|
possible. Hence, before including an external library, please ask the team for
|
||
|
review.
|
||
|
|
||
|
Examples of currently used libraries:
|
||
|
|
||
|
* boringssl: Google's openssl implementation
|
||
|
* small parts of libchrome, to be removed or replaced eventually
|
||
|
* base::OnceCallback
|
||
|
* base::Callback
|
||
|
* base::BindOnce
|
||
|
* base::Bind
|
||
|
* google-breakpad: host binary crash handler
|
||
|
* libbacktrace: print stacktrace on crash on host
|
||
|
|
||
|
## Exposed symbols
|
||
|
|
||
|
Given that entire Fluoride library is held in libbluetooth.so dynamic library
|
||
|
file, we need a way to load this library and extract entry points to it. The
|
||
|
only symbols that should be exposed are:
|
||
|
|
||
|
* An entry point to a normal running adapter module libbluetooth.so
|
||
|
* A header library to all exposed API service to profiles and layers
|
||
|
* An entry point to a certification interface, libbluetooth\_certification.so
|
||
|
* A header library to this certification stack
|
||
|
|
||
|
## Logging
|
||
|
|
||
|
Gabeldorsche uses `printf` style logging with macros defined in `os/log.h`. Five
|
||
|
log levels are available.
|
||
|
|
||
|
* LOG_VERBOSE(fmt, args...): Will be disabled by default
|
||
|
* LOG_INFO(fmt, args...): Will be disabled by default
|
||
|
* LOG_INFO(fmt, args...): Enabled
|
||
|
* LOG_WARN(fmt, args...): Enabled
|
||
|
* LOG_ERROR(fmt, args...): Enabled
|
||
|
* LOG_ALWAYS_FATAL(fmt, args...): Enabled, will always crash
|
||
|
* ASSERT(condition): Enabled, will crash when condition is false
|
||
|
* ASSERT_LOG(conditon, fmt, args...): Enabled, will crash and print log when
|
||
|
condition is false
|
||
|
|
||
|
In general, errors that are caused by remote device should never crash our stack
|
||
|
and should be logged using LOG_WARN() only. Recoverable errors due to our stack
|
||
|
or badly behaved bluetooth controller firmware should be logged using
|
||
|
LOG_ERROR() before recovery. Non-recoverable errors should be logged as
|
||
|
LOG_ALWAYS_FATAL() to crash the stack and restart.
|