DO NOT MERGE ANYWHERE Provide HFP API to set AG SCO policy am: bf47a8ec52  -s ours
am: c739a0dd03  -s ours

Change-Id: Ia24d927036e43f48831651e91415752a1ae319ab
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..f6aacd2
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,38 @@
+// Copyright 2006 The Android Open Source Project
+
+cc_library_headers {
+    name: "libhardware_headers",
+    header_libs: [
+        "libaudio_system_headers",
+        "libsystem_headers",
+    ],
+    export_header_lib_headers: [
+        "libaudio_system_headers",
+        "libsystem_headers"
+    ],
+
+    export_include_dirs: ["include"],
+    vendor_available: true,
+}
+
+cc_library_shared {
+    name: "libhardware",
+
+    srcs: ["hardware.c"],
+    shared_libs: [
+        "libcutils",
+        "liblog",
+        "libdl",
+    ],
+    cflags: ["-DQEMU_HARDWARE"],
+
+    header_libs: ["libhardware_headers"],
+    export_header_lib_headers: ["libhardware_headers"],
+
+    vendor_available: true,
+}
+
+subdirs = [
+    "modules/*",
+    "tests/*",
+]
diff --git a/Android.mk b/Android.mk
index aec6781..8744f46 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,24 +1,3 @@
 # Copyright 2006 The Android Open Source Project
 
-# Setting LOCAL_PATH will mess up all-subdir-makefiles, so do it beforehand.
-SUBDIR_MAKEFILES := $(call all-named-subdir-makefiles,modules tests)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SHARED_LIBRARIES := libcutils liblog
-
-LOCAL_INCLUDES += $(LOCAL_PATH)
-
-LOCAL_CFLAGS  += -DQEMU_HARDWARE
-QEMU_HARDWARE := true
-
-LOCAL_SHARED_LIBRARIES += libdl
-
-LOCAL_SRC_FILES += hardware.c
-
-LOCAL_MODULE:= libhardware
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(SUBDIR_MAKEFILES)
+include $(call all-named-subdir-makefiles,modules tests)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b84e1b6..1c64bfc 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -47,3 +47,13 @@
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
+
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib/libdynamic_sensor_ext.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib64/libdynamic_sensor_ext.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib/hw/sensors.dynamic_sensor_hal.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib64/hw/sensors.dynamic_sensor_hal.so)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
diff --git a/hardware.c b/hardware.c
index 5394787..7e4debe 100644
--- a/hardware.c
+++ b/hardware.c
@@ -23,9 +23,11 @@
 #include <pthread.h>
 #include <errno.h>
 #include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
 
 #define LOG_TAG "HAL"
-#include <utils/Log.h>
+#include <log/log.h>
 
 /** Base path of the hal modules */
 #if defined(__LP64__)
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index ec7fd4b..2d6eb30 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -22,6 +22,7 @@
 #include <strings.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
+#include <time.h>
 
 #include <cutils/bitops.h>
 
@@ -59,19 +60,6 @@
 /* Minimal audio HAL version supported by the audio framework */
 #define AUDIO_DEVICE_API_VERSION_MIN AUDIO_DEVICE_API_VERSION_2_0
 
-/**
- * List of known audio HAL modules. This is the base name of the audio HAL
- * library composed of the "audio." prefix, one of the base names below and
- * a suffix specific to the device.
- * e.g: audio.primary.goldfish.so or audio.a2dp.default.so
- */
-
-#define AUDIO_HARDWARE_MODULE_ID_PRIMARY "primary"
-#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp"
-#define AUDIO_HARDWARE_MODULE_ID_USB "usb"
-#define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix"
-#define AUDIO_HARDWARE_MODULE_ID_CODEC_OFFLOAD "codec_offload"
-
 /**************************************/
 
 /**
@@ -82,11 +70,6 @@
  *  audio device parameters
  */
 
-/* BT SCO Noise Reduction + Echo Cancellation parameters */
-#define AUDIO_PARAMETER_KEY_BT_NREC "bt_headset_nrec"
-#define AUDIO_PARAMETER_VALUE_ON "on"
-#define AUDIO_PARAMETER_VALUE_OFF "off"
-
 /* TTY mode selection */
 #define AUDIO_PARAMETER_KEY_TTY_MODE "tty_mode"
 #define AUDIO_PARAMETER_VALUE_TTY_OFF "tty_off"
@@ -94,8 +77,7 @@
 #define AUDIO_PARAMETER_VALUE_TTY_HCO "tty_hco"
 #define AUDIO_PARAMETER_VALUE_TTY_FULL "tty_full"
 
-/* Hearing Aid Compatibility - Telecoil (HAC-T) mode on/off
-   Strings must be in sync with CallFeaturesSetting.java */
+/* Hearing Aid Compatibility - Telecoil (HAC-T) mode on/off */
 #define AUDIO_PARAMETER_KEY_HAC "HACSetting"
 #define AUDIO_PARAMETER_VALUE_HAC_ON "ON"
 #define AUDIO_PARAMETER_VALUE_HAC_OFF "OFF"
@@ -106,63 +88,15 @@
 /* A2DP source address set by framework */
 #define AUDIO_PARAMETER_A2DP_SOURCE_ADDRESS "a2dp_source_address"
 
-/* Screen state */
-#define AUDIO_PARAMETER_KEY_SCREEN_STATE "screen_state"
-
 /* Bluetooth SCO wideband */
 #define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs"
 
-/* Get a new HW synchronization source identifier.
- * Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs
- * or no HW sync is available. */
-#define AUDIO_PARAMETER_HW_AV_SYNC "hw_av_sync"
-
 /**
  *  audio stream parameters
  */
 
-#define AUDIO_PARAMETER_STREAM_ROUTING "routing"             /* audio_devices_t */
-#define AUDIO_PARAMETER_STREAM_FORMAT "format"               /* audio_format_t */
-#define AUDIO_PARAMETER_STREAM_CHANNELS "channels"           /* audio_channel_mask_t */
-#define AUDIO_PARAMETER_STREAM_FRAME_COUNT "frame_count"     /* size_t */
-#define AUDIO_PARAMETER_STREAM_INPUT_SOURCE "input_source"   /* audio_source_t */
-#define AUDIO_PARAMETER_STREAM_SAMPLING_RATE "sampling_rate" /* uint32_t */
-
-#define AUDIO_PARAMETER_DEVICE_CONNECT "connect"            /* audio_devices_t */
-#define AUDIO_PARAMETER_DEVICE_DISCONNECT "disconnect"      /* audio_devices_t */
-
-/* Query supported formats. The response is a '|' separated list of strings from
- * audio_format_t enum e.g: "sup_formats=AUDIO_FORMAT_PCM_16_BIT" */
-#define AUDIO_PARAMETER_STREAM_SUP_FORMATS "sup_formats"
-/* Query supported channel masks. The response is a '|' separated list of strings from
- * audio_channel_mask_t enum e.g: "sup_channels=AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_MONO" */
-#define AUDIO_PARAMETER_STREAM_SUP_CHANNELS "sup_channels"
-/* Query supported sampling rates. The response is a '|' separated list of integer values e.g:
- * "sup_sampling_rates=44100|48000" */
-#define AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES "sup_sampling_rates"
-
-/* Set the HW synchronization source for an output stream. */
-#define AUDIO_PARAMETER_STREAM_HW_AV_SYNC "hw_av_sync"
-
-/* Enable mono audio playback if 1, else should be 0. */
-#define AUDIO_PARAMETER_MONO_OUTPUT "mono_output"
-
-/**
- * audio codec parameters
- */
-
-#define AUDIO_OFFLOAD_CODEC_PARAMS "music_offload_codec_param"
-#define AUDIO_OFFLOAD_CODEC_BIT_PER_SAMPLE "music_offload_bit_per_sample"
-#define AUDIO_OFFLOAD_CODEC_BIT_RATE "music_offload_bit_rate"
-#define AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE "music_offload_avg_bit_rate"
-#define AUDIO_OFFLOAD_CODEC_ID "music_offload_codec_id"
-#define AUDIO_OFFLOAD_CODEC_BLOCK_ALIGN "music_offload_block_align"
-#define AUDIO_OFFLOAD_CODEC_SAMPLE_RATE "music_offload_sample_rate"
-#define AUDIO_OFFLOAD_CODEC_ENCODE_OPTION "music_offload_encode_option"
-#define AUDIO_OFFLOAD_CODEC_NUM_CHANNEL  "music_offload_num_channels"
-#define AUDIO_OFFLOAD_CODEC_DOWN_SAMPLING  "music_offload_down_sampling"
-#define AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES  "delay_samples"
-#define AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES  "padding_samples"
+/* Enable AANC */
+#define AUDIO_PARAMETER_KEY_AANC "aanc_enabled"
 
 /**************************************/
 
@@ -399,6 +333,65 @@
     int (*get_presentation_position)(const struct audio_stream_out *stream,
                                uint64_t *frames, struct timespec *timestamp);
 
+    /**
+     * Called by the framework to start a stream operating in mmap mode.
+     * create_mmap_buffer must be called before calling start()
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \return 0 in case of success.
+     *         -ENOSYS if called out of sequence or on non mmap stream
+     */
+    int (*start)(const struct audio_stream_out* stream);
+
+    /**
+     * Called by the framework to stop a stream operating in mmap mode.
+     * Must be called after start()
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \return 0 in case of success.
+     *         -ENOSYS if called out of sequence or on non mmap stream
+     */
+    int (*stop)(const struct audio_stream_out* stream);
+
+    /**
+     * Called by the framework to retrieve information on the mmap buffer used for audio
+     * samples transfer.
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \param[in] min_size_frames minimum buffer size requested. The actual buffer
+     *        size returned in struct audio_mmap_buffer_info can be larger.
+     * \param[out] info address at which the mmap buffer information should be returned.
+     *
+     * \return 0 if the buffer was allocated.
+     *         -ENODEV in case of initialization error
+     *         -EINVAL if the requested buffer size is too large
+     *         -ENOSYS if called out of sequence (e.g. buffer already allocated)
+     */
+    int (*create_mmap_buffer)(const struct audio_stream_out *stream,
+                              int32_t min_size_frames,
+                              struct audio_mmap_buffer_info *info);
+
+    /**
+     * Called by the framework to read current read/write position in the mmap buffer
+     * with associated time stamp.
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \param[out] position address at which the mmap read/write position should be returned.
+     *
+     * \return 0 if the position is successfully returned.
+     *         -ENODATA if the position cannot be retrieved
+     *         -ENOSYS if called before create_mmap_buffer()
+     */
+    int (*get_mmap_position)(const struct audio_stream_out *stream,
+                             struct audio_mmap_position *position);
 };
 typedef struct audio_stream_out audio_stream_out_t;
 
@@ -449,6 +442,65 @@
      */
     int (*get_capture_position)(const struct audio_stream_in *stream,
                                 int64_t *frames, int64_t *time);
+
+    /**
+     * Called by the framework to start a stream operating in mmap mode.
+     * create_mmap_buffer must be called before calling start()
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \return 0 in case off success.
+     *         -ENOSYS if called out of sequence or on non mmap stream
+     */
+    int (*start)(const struct audio_stream_in* stream);
+
+    /**
+     * Called by the framework to stop a stream operating in mmap mode.
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \return 0 in case of success.
+     *         -ENOSYS if called out of sequence or on non mmap stream
+     */
+    int (*stop)(const struct audio_stream_in* stream);
+
+    /**
+     * Called by the framework to retrieve information on the mmap buffer used for audio
+     * samples transfer.
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \param[in] min_size_frames minimum buffer size requested. The actual buffer
+     *        size returned in struct audio_mmap_buffer_info can be larger.
+     * \param[out] info address at which the mmap buffer information should be returned.
+     *
+     * \return 0 if the buffer was allocated.
+     *         -ENODEV in case of initialization error
+     *         -EINVAL if the requested buffer size is too large
+     *         -ENOSYS if called out of sequence (e.g. buffer already allocated)
+     */
+    int (*create_mmap_buffer)(const struct audio_stream_in *stream,
+                              int32_t min_size_frames,
+                              struct audio_mmap_buffer_info *info);
+
+    /**
+     * Called by the framework to read current read/write position in the mmap buffer
+     * with associated time stamp.
+     *
+     * \note Function only implemented by streams operating in mmap mode.
+     *
+     * \param[in] stream the stream object.
+     * \param[out] position address at which the mmap read/write position should be returned.
+     *
+     * \return 0 if the position is successfully returned.
+     *         -ENODATA if the position cannot be retreived
+     *         -ENOSYS if called before mmap_read_position()
+     */
+    int (*get_mmap_position)(const struct audio_stream_in *stream,
+                             struct audio_mmap_position *position);
 };
 typedef struct audio_stream_in audio_stream_in_t;
 
@@ -679,7 +731,7 @@
                                        struct audio_hw_device** device)
 {
     return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
-                                 (struct hw_device_t**)device);
+                                 TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int audio_hw_device_close(struct audio_hw_device* device)
diff --git a/include/hardware/audio_alsaops.h b/include/hardware/audio_alsaops.h
index 0d266ff..e994924 100644
--- a/include/hardware/audio_alsaops.h
+++ b/include/hardware/audio_alsaops.h
@@ -37,7 +37,7 @@
 static inline enum pcm_format pcm_format_from_audio_format(audio_format_t format)
 {
     switch (format) {
-#ifdef HAVE_BIG_ENDIAN
+#if HAVE_BIG_ENDIAN
     case AUDIO_FORMAT_PCM_16_BIT:
         return PCM_FORMAT_S16_BE;
     case AUDIO_FORMAT_PCM_24_BIT_PACKED:
@@ -72,7 +72,7 @@
 static inline audio_format_t audio_format_from_pcm_format(enum pcm_format format)
 {
     switch (format) {
-#ifdef HAVE_BIG_ENDIAN
+#if HAVE_BIG_ENDIAN
     case PCM_FORMAT_S16_BE:
         return AUDIO_FORMAT_PCM_16_BIT;
     case PCM_FORMAT_S24_3BE:
diff --git a/include/hardware/audio_effect.h b/include/hardware/audio_effect.h
index 8a88414..3366e17 100644
--- a/include/hardware/audio_effect.h
+++ b/include/hardware/audio_effect.h
@@ -26,7 +26,7 @@
 
 #include <cutils/bitops.h>
 
-#include <system/audio.h>
+#include <system/audio_effect.h>
 
 
 __BEGIN_DECLS
@@ -36,231 +36,11 @@
 //      Common Definitions
 /////////////////////////////////////////////////
 
-//
-//--- Effect descriptor structure effect_descriptor_t
-//
-
-// Unique effect ID (can be generated from the following site:
-//  http://www.itu.int/ITU-T/asn1/uuid.html)
-// This format is used for both "type" and "uuid" fields of the effect descriptor structure.
-// - When used for effect type and the engine is implementing and effect corresponding to a standard
-// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface.
-// - When used as uuid, it should be a unique UUID for this particular implementation.
-typedef struct effect_uuid_s {
-    uint32_t timeLow;
-    uint16_t timeMid;
-    uint16_t timeHiAndVersion;
-    uint16_t clockSeq;
-    uint8_t node[6];
-} effect_uuid_t;
-
-// Maximum length of character strings in structures defines by this API.
-#define EFFECT_STRING_LEN_MAX 64
-
-// NULL UUID definition (matches SL_IID_NULL_)
-#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \
-                                  { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } }
-static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER;
-static const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_;
-static const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210";
-
-
-// The effect descriptor contains necessary information to facilitate the enumeration of the effect
-// engines present in a library.
-typedef struct effect_descriptor_s {
-    effect_uuid_t type;     // UUID of to the OpenSL ES interface implemented by this effect
-    effect_uuid_t uuid;     // UUID for this particular implementation
-    uint32_t apiVersion;    // Version of the effect control API implemented
-    uint32_t flags;         // effect engine capabilities/requirements flags (see below)
-    uint16_t cpuLoad;       // CPU load indication (see below)
-    uint16_t memoryUsage;   // Data Memory usage (see below)
-    char    name[EFFECT_STRING_LEN_MAX];   // human readable effect name
-    char    implementor[EFFECT_STRING_LEN_MAX];    // human readable effect implementor name
-} effect_descriptor_t;
-
-// CPU load and memory usage indication: each effect implementation must provide an indication of
-// its CPU and memory usage for the audio effect framework to limit the number of effects
-// instantiated at a given time on a given platform.
-// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS.
-// The memory usage is expressed in KB and includes only dynamically allocated memory
-
-// Definitions for flags field of effect descriptor.
-//  +---------------------------+-----------+-----------------------------------
-//  | description               | bits      | values
-//  +---------------------------+-----------+-----------------------------------
-//  | connection mode           | 0..2      | 0 insert: after track process
-//  |                           |           | 1 auxiliary: connect to track auxiliary
-//  |                           |           |  output and use send level
-//  |                           |           | 2 replace: replaces track process function;
-//  |                           |           |   must implement SRC, volume and mono to stereo.
-//  |                           |           | 3 pre processing: applied below audio HAL on input
-//  |                           |           | 4 post processing: applied below audio HAL on output
-//  |                           |           | 5 - 7 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | insertion preference      | 3..5      | 0 none
-//  |                           |           | 1 first of the chain
-//  |                           |           | 2 last of the chain
-//  |                           |           | 3 exclusive (only effect in the insert chain)
-//  |                           |           | 4..7 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Volume management         | 6..8      | 0 none
-//  |                           |           | 1 implements volume control
-//  |                           |           | 2 requires volume indication
-//  |                           |           | 4 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Device indication         | 9..11     | 0 none
-//  |                           |           | 1 requires device updates
-//  |                           |           | 2, 4 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Sample input mode         | 12..13    | 1 direct: process() function or EFFECT_CMD_SET_CONFIG
-//  |                           |           |   command must specify a buffer descriptor
-//  |                           |           | 2 provider: process() function uses the
-//  |                           |           |   bufferProvider indicated by the
-//  |                           |           |   EFFECT_CMD_SET_CONFIG command to request input.
-//  |                           |           |   buffers.
-//  |                           |           | 3 both: both input modes are supported
-//  +---------------------------+-----------+-----------------------------------
-//  | Sample output mode        | 14..15    | 1 direct: process() function or EFFECT_CMD_SET_CONFIG
-//  |                           |           |   command must specify a buffer descriptor
-//  |                           |           | 2 provider: process() function uses the
-//  |                           |           |   bufferProvider indicated by the
-//  |                           |           |   EFFECT_CMD_SET_CONFIG command to request output
-//  |                           |           |   buffers.
-//  |                           |           | 3 both: both output modes are supported
-//  +---------------------------+-----------+-----------------------------------
-//  | Hardware acceleration     | 16..17    | 0 No hardware acceleration
-//  |                           |           | 1 non tunneled hw acceleration: the process() function
-//  |                           |           |   reads the samples, send them to HW accelerated
-//  |                           |           |   effect processor, reads back the processed samples
-//  |                           |           |   and returns them to the output buffer.
-//  |                           |           | 2 tunneled hw acceleration: the process() function is
-//  |                           |           |   transparent. The effect interface is only used to
-//  |                           |           |   control the effect engine. This mode is relevant for
-//  |                           |           |   global effects actually applied by the audio
-//  |                           |           |   hardware on the output stream.
-//  +---------------------------+-----------+-----------------------------------
-//  | Audio Mode indication     | 18..19    | 0 none
-//  |                           |           | 1 requires audio mode updates
-//  |                           |           | 2..3 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Audio source indication   | 20..21    | 0 none
-//  |                           |           | 1 requires audio source updates
-//  |                           |           | 2..3 reserved
-//  +---------------------------+-----------+-----------------------------------
-//  | Effect offload supported  | 22        | 0 The effect cannot be offloaded to an audio DSP
-//  |                           |           | 1 The effect can be offloaded to an audio DSP
-//  +---------------------------+-----------+-----------------------------------
-//  | Process function not      | 23        | 0 The effect implements a process function.
-//  | implemented               |           | 1 The effect does not implement a process function:
-//  |                           |           |   enabling the effect has no impact on latency or
-//  |                           |           |   CPU load.
-//  |                           |           |   Effect implementations setting this flag do not have
-//  |                           |           |   to implement a process function.
-//  +---------------------------+-----------+-----------------------------------
-
-// Insert mode
-#define EFFECT_FLAG_TYPE_SHIFT          0
-#define EFFECT_FLAG_TYPE_SIZE           3
-#define EFFECT_FLAG_TYPE_MASK           (((1 << EFFECT_FLAG_TYPE_SIZE) -1) \
-                                            << EFFECT_FLAG_TYPE_SHIFT)
-#define EFFECT_FLAG_TYPE_INSERT         (0 << EFFECT_FLAG_TYPE_SHIFT)
-#define EFFECT_FLAG_TYPE_AUXILIARY      (1 << EFFECT_FLAG_TYPE_SHIFT)
-#define EFFECT_FLAG_TYPE_REPLACE        (2 << EFFECT_FLAG_TYPE_SHIFT)
-#define EFFECT_FLAG_TYPE_PRE_PROC       (3 << EFFECT_FLAG_TYPE_SHIFT)
-#define EFFECT_FLAG_TYPE_POST_PROC      (4 << EFFECT_FLAG_TYPE_SHIFT)
-
-// Insert preference
-#define EFFECT_FLAG_INSERT_SHIFT        (EFFECT_FLAG_TYPE_SHIFT + EFFECT_FLAG_TYPE_SIZE)
-#define EFFECT_FLAG_INSERT_SIZE         3
-#define EFFECT_FLAG_INSERT_MASK         (((1 << EFFECT_FLAG_INSERT_SIZE) -1) \
-                                            << EFFECT_FLAG_INSERT_SHIFT)
-#define EFFECT_FLAG_INSERT_ANY          (0 << EFFECT_FLAG_INSERT_SHIFT)
-#define EFFECT_FLAG_INSERT_FIRST        (1 << EFFECT_FLAG_INSERT_SHIFT)
-#define EFFECT_FLAG_INSERT_LAST         (2 << EFFECT_FLAG_INSERT_SHIFT)
-#define EFFECT_FLAG_INSERT_EXCLUSIVE    (3 << EFFECT_FLAG_INSERT_SHIFT)
-
-
-// Volume control
-#define EFFECT_FLAG_VOLUME_SHIFT        (EFFECT_FLAG_INSERT_SHIFT + EFFECT_FLAG_INSERT_SIZE)
-#define EFFECT_FLAG_VOLUME_SIZE         3
-#define EFFECT_FLAG_VOLUME_MASK         (((1 << EFFECT_FLAG_VOLUME_SIZE) -1) \
-                                            << EFFECT_FLAG_VOLUME_SHIFT)
-#define EFFECT_FLAG_VOLUME_CTRL         (1 << EFFECT_FLAG_VOLUME_SHIFT)
-#define EFFECT_FLAG_VOLUME_IND          (2 << EFFECT_FLAG_VOLUME_SHIFT)
-#define EFFECT_FLAG_VOLUME_NONE         (0 << EFFECT_FLAG_VOLUME_SHIFT)
-
-// Device indication
-#define EFFECT_FLAG_DEVICE_SHIFT        (EFFECT_FLAG_VOLUME_SHIFT + EFFECT_FLAG_VOLUME_SIZE)
-#define EFFECT_FLAG_DEVICE_SIZE         3
-#define EFFECT_FLAG_DEVICE_MASK         (((1 << EFFECT_FLAG_DEVICE_SIZE) -1) \
-                                            << EFFECT_FLAG_DEVICE_SHIFT)
-#define EFFECT_FLAG_DEVICE_IND          (1 << EFFECT_FLAG_DEVICE_SHIFT)
-#define EFFECT_FLAG_DEVICE_NONE         (0 << EFFECT_FLAG_DEVICE_SHIFT)
-
-// Sample input modes
-#define EFFECT_FLAG_INPUT_SHIFT         (EFFECT_FLAG_DEVICE_SHIFT + EFFECT_FLAG_DEVICE_SIZE)
-#define EFFECT_FLAG_INPUT_SIZE          2
-#define EFFECT_FLAG_INPUT_MASK          (((1 << EFFECT_FLAG_INPUT_SIZE) -1) \
-                                            << EFFECT_FLAG_INPUT_SHIFT)
-#define EFFECT_FLAG_INPUT_DIRECT        (1 << EFFECT_FLAG_INPUT_SHIFT)
-#define EFFECT_FLAG_INPUT_PROVIDER      (2 << EFFECT_FLAG_INPUT_SHIFT)
-#define EFFECT_FLAG_INPUT_BOTH          (3 << EFFECT_FLAG_INPUT_SHIFT)
-
-// Sample output modes
-#define EFFECT_FLAG_OUTPUT_SHIFT        (EFFECT_FLAG_INPUT_SHIFT + EFFECT_FLAG_INPUT_SIZE)
-#define EFFECT_FLAG_OUTPUT_SIZE         2
-#define EFFECT_FLAG_OUTPUT_MASK         (((1 << EFFECT_FLAG_OUTPUT_SIZE) -1) \
-                                            << EFFECT_FLAG_OUTPUT_SHIFT)
-#define EFFECT_FLAG_OUTPUT_DIRECT       (1 << EFFECT_FLAG_OUTPUT_SHIFT)
-#define EFFECT_FLAG_OUTPUT_PROVIDER     (2 << EFFECT_FLAG_OUTPUT_SHIFT)
-#define EFFECT_FLAG_OUTPUT_BOTH         (3 << EFFECT_FLAG_OUTPUT_SHIFT)
-
-// Hardware acceleration mode
-#define EFFECT_FLAG_HW_ACC_SHIFT        (EFFECT_FLAG_OUTPUT_SHIFT + EFFECT_FLAG_OUTPUT_SIZE)
-#define EFFECT_FLAG_HW_ACC_SIZE         2
-#define EFFECT_FLAG_HW_ACC_MASK         (((1 << EFFECT_FLAG_HW_ACC_SIZE) -1) \
-                                            << EFFECT_FLAG_HW_ACC_SHIFT)
-#define EFFECT_FLAG_HW_ACC_SIMPLE       (1 << EFFECT_FLAG_HW_ACC_SHIFT)
-#define EFFECT_FLAG_HW_ACC_TUNNEL       (2 << EFFECT_FLAG_HW_ACC_SHIFT)
-
-// Audio mode indication
-#define EFFECT_FLAG_AUDIO_MODE_SHIFT    (EFFECT_FLAG_HW_ACC_SHIFT + EFFECT_FLAG_HW_ACC_SIZE)
-#define EFFECT_FLAG_AUDIO_MODE_SIZE     2
-#define EFFECT_FLAG_AUDIO_MODE_MASK     (((1 << EFFECT_FLAG_AUDIO_MODE_SIZE) -1) \
-                                            << EFFECT_FLAG_AUDIO_MODE_SHIFT)
-#define EFFECT_FLAG_AUDIO_MODE_IND      (1 << EFFECT_FLAG_AUDIO_MODE_SHIFT)
-#define EFFECT_FLAG_AUDIO_MODE_NONE     (0 << EFFECT_FLAG_AUDIO_MODE_SHIFT)
-
-// Audio source indication
-#define EFFECT_FLAG_AUDIO_SOURCE_SHIFT  (EFFECT_FLAG_AUDIO_MODE_SHIFT + EFFECT_FLAG_AUDIO_MODE_SIZE)
-#define EFFECT_FLAG_AUDIO_SOURCE_SIZE   2
-#define EFFECT_FLAG_AUDIO_SOURCE_MASK   (((1 << EFFECT_FLAG_AUDIO_SOURCE_SIZE) -1) \
-                                          << EFFECT_FLAG_AUDIO_SOURCE_SHIFT)
-#define EFFECT_FLAG_AUDIO_SOURCE_IND    (1 << EFFECT_FLAG_AUDIO_SOURCE_SHIFT)
-#define EFFECT_FLAG_AUDIO_SOURCE_NONE   (0 << EFFECT_FLAG_AUDIO_SOURCE_SHIFT)
-
-// Effect offload indication
-#define EFFECT_FLAG_OFFLOAD_SHIFT       (EFFECT_FLAG_AUDIO_SOURCE_SHIFT + \
-                                                    EFFECT_FLAG_AUDIO_SOURCE_SIZE)
-#define EFFECT_FLAG_OFFLOAD_SIZE        1
-#define EFFECT_FLAG_OFFLOAD_MASK        (((1 << EFFECT_FLAG_OFFLOAD_SIZE) -1) \
-                                          << EFFECT_FLAG_OFFLOAD_SHIFT)
-#define EFFECT_FLAG_OFFLOAD_SUPPORTED   (1 << EFFECT_FLAG_OFFLOAD_SHIFT)
-
-// Effect has no process indication
-#define EFFECT_FLAG_NO_PROCESS_SHIFT       (EFFECT_FLAG_OFFLOAD_SHIFT + \
-                                                    EFFECT_FLAG_OFFLOAD_SIZE)
-#define EFFECT_FLAG_NO_PROCESS_SIZE        1
-#define EFFECT_FLAG_NO_PROCESS_MASK        (((1 << EFFECT_FLAG_NO_PROCESS_SIZE) -1) \
-                                          << EFFECT_FLAG_NO_PROCESS_SHIFT)
-#define EFFECT_FLAG_NO_PROCESS          (1 << EFFECT_FLAG_NO_PROCESS_SHIFT)
-
 #define EFFECT_MAKE_API_VERSION(M, m)  (((M)<<16) | ((m) & 0xFFFF))
 #define EFFECT_API_VERSION_MAJOR(v)    ((v)>>16)
 #define EFFECT_API_VERSION_MINOR(v)    ((m) & 0xFFFF)
 
 
-
 /////////////////////////////////////////////////
 //      Effect control interface
 /////////////////////////////////////////////////
@@ -288,15 +68,6 @@
 // type and return its address as effect_handle_t
 typedef struct effect_interface_s **effect_handle_t;
 
-
-// Forward definition of type audio_buffer_t
-typedef struct audio_buffer_s audio_buffer_t;
-
-
-
-
-
-
 // Effect control interface definition
 struct effect_interface_s {
     ////////////////////////////////////////////////////////////////////////////////
@@ -428,499 +199,6 @@
                                audio_buffer_t *outBuffer);
 };
 
-
-//
-//--- Standardized command codes for command() function
-//
-enum effect_command_e {
-   EFFECT_CMD_INIT,                 // initialize effect engine
-   EFFECT_CMD_SET_CONFIG,           // configure effect engine (see effect_config_t)
-   EFFECT_CMD_RESET,                // reset effect engine
-   EFFECT_CMD_ENABLE,               // enable effect process
-   EFFECT_CMD_DISABLE,              // disable effect process
-   EFFECT_CMD_SET_PARAM,            // set parameter immediately (see effect_param_t)
-   EFFECT_CMD_SET_PARAM_DEFERRED,   // set parameter deferred
-   EFFECT_CMD_SET_PARAM_COMMIT,     // commit previous set parameter deferred
-   EFFECT_CMD_GET_PARAM,            // get parameter
-   EFFECT_CMD_SET_DEVICE,           // set audio device (see audio.h, audio_devices_t)
-   EFFECT_CMD_SET_VOLUME,           // set volume
-   EFFECT_CMD_SET_AUDIO_MODE,       // set the audio mode (normal, ring, ...)
-   EFFECT_CMD_SET_CONFIG_REVERSE,   // configure effect engine reverse stream(see effect_config_t)
-   EFFECT_CMD_SET_INPUT_DEVICE,     // set capture device (see audio.h, audio_devices_t)
-   EFFECT_CMD_GET_CONFIG,           // read effect engine configuration
-   EFFECT_CMD_GET_CONFIG_REVERSE,   // read configure effect engine reverse stream configuration
-   EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,// get all supported configurations for a feature.
-   EFFECT_CMD_GET_FEATURE_CONFIG,   // get current feature configuration
-   EFFECT_CMD_SET_FEATURE_CONFIG,   // set current feature configuration
-   EFFECT_CMD_SET_AUDIO_SOURCE,     // set the audio source (see audio.h, audio_source_t)
-   EFFECT_CMD_OFFLOAD,              // set if effect thread is an offload one,
-                                    // send the ioHandle of the effect thread
-   EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code
-};
-
-//==================================================================================================
-// command: EFFECT_CMD_INIT
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Initialize effect engine: All configurations return to default
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_CONFIG
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Apply new audio parameters configurations for input and output buffers
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_config_t)
-//  data: effect_config_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_RESET
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Reset the effect engine. Keep configuration but resets state and buffer content
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_ENABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Enable the process. Called by the framework before the first call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_DISABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Disable the process. Called by the framework after the last call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set a parameter and apply it immediately
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_param_t) + size of param and value
-//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_DEFERRED
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_param_t) + size of param and value
-//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_COMMIT
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_GET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Get a parameter value
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_param_t) + size of param
-//  data: effect_param_t + param
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(effect_param_t) + size of param and value
-//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//==================================================================================================
-// command: EFFECT_CMD_SET_DEVICE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set the rendering device the audio output path is connected to. See audio.h, audio_devices_t
-//  for device values.
-//  The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
-//  command when the device changes
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t)
-//  data: uint32_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_VOLUME
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set and get volume. Used by audio framework to delegate volume control to effect engine.
-//  The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in
-//  its descriptor to receive this command before every call to process() function
-//  If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return
-//  the volume that should be applied before the effect is processed. The overall volume (the volume
-//  actually applied by the effect engine multiplied by the returned value) should match the value
-//  indicated in the command.
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: n * sizeof(uint32_t)
-//  data: volume for each channel defined in effect_config_t for output buffer expressed in
-//      8.24 fixed point format
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: n * sizeof(uint32_t) / 0
-//  data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor:
-//              volume for each channel defined in effect_config_t for output buffer expressed in
-//              8.24 fixed point format
-//        - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor:
-//              N/A
-//  It is legal to receive a null pointer as pReplyData in which case the effect framework has
-//  delegated volume control to another effect
-//==================================================================================================
-// command: EFFECT_CMD_SET_AUDIO_MODE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its
-//  descriptor to receive this command when the audio mode changes.
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t)
-//  data: audio_mode_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_CONFIG_REVERSE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Apply new audio parameters configurations for input and output buffers of reverse stream.
-//  An example of reverse stream is the echo reference supplied to an Acoustic Echo Canceler.
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_config_t)
-//  data: effect_config_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(int)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_INPUT_DEVICE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set the capture device the audio input path is connected to. See audio.h, audio_devices_t
-//  for device values.
-//  The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
-//  command when the device changes
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t)
-//  data: uint32_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_GET_CONFIG
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Read audio parameters configurations for input and output buffers
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(effect_config_t)
-//  data: effect_config_t
-//==================================================================================================
-// command: EFFECT_CMD_GET_CONFIG_REVERSE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Read audio parameters configurations for input and output buffers of reverse stream
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 0
-//  data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(effect_config_t)
-//  data: effect_config_t
-//==================================================================================================
-// command: EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Queries for supported configurations for a particular feature (e.g. get the supported
-// combinations of main and auxiliary channels for a noise suppressor).
-// The command parameter is the feature identifier (See effect_feature_e for a list of defined
-// features) followed by the maximum number of configuration descriptor to return.
-// The reply is composed of:
-//  - status (uint32_t):
-//          - 0 if feature is supported
-//          - -ENOSYS if the feature is not supported,
-//          - -ENOMEM if the feature is supported but the total number of supported configurations
-//          exceeds the maximum number indicated by the caller.
-//  - total number of supported configurations (uint32_t)
-//  - an array of configuration descriptors.
-// The actual number of descriptors returned must not exceed the maximum number indicated by
-// the caller.
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: 2 x sizeof(uint32_t)
-//  data: effect_feature_e + maximum number of configurations to return
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 2 x sizeof(uint32_t) + n x sizeof (<config descriptor>)
-//  data: status + total number of configurations supported + array of n config descriptors
-//==================================================================================================
-// command: EFFECT_CMD_GET_FEATURE_CONFIG
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Retrieves current configuration for a given feature.
-// The reply status is:
-//      - 0 if feature is supported
-//      - -ENOSYS if the feature is not supported,
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t)
-//  data: effect_feature_e
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(uint32_t) + sizeof (<config descriptor>)
-//  data: status + config descriptor
-//==================================================================================================
-// command: EFFECT_CMD_SET_FEATURE_CONFIG
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Sets current configuration for a given feature.
-// The reply status is:
-//      - 0 if feature is supported
-//      - -ENOSYS if the feature is not supported,
-//      - -EINVAL if the configuration is invalid
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t) + sizeof (<config descriptor>)
-//  data: effect_feature_e + config descriptor
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(uint32_t)
-//  data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_AUDIO_SOURCE
-//--------------------------------------------------------------------------------------------------
-// description:
-//  Set the audio source the capture path is configured for (Camcorder, voice recognition...).
-//  See audio.h, audio_source_t for values.
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(uint32_t)
-//  data: uint32_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: 0
-//  data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_OFFLOAD
-//--------------------------------------------------------------------------------------------------
-// description:
-//  1.indicate if the playback thread the effect is attached to is offloaded or not
-//  2.update the io handle of the playback thread the effect is attached to
-//--------------------------------------------------------------------------------------------------
-// command format:
-//  size: sizeof(effect_offload_param_t)
-//  data: effect_offload_param_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-//  size: sizeof(uint32_t)
-//  data: uint32_t
-//--------------------------------------------------------------------------------------------------
-// command: EFFECT_CMD_FIRST_PROPRIETARY
-//--------------------------------------------------------------------------------------------------
-// description:
-//  All proprietary effect commands must use command codes above this value. The size and format of
-//  command and response fields is free in this case
-//==================================================================================================
-
-
-// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t
-// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with
-// regard to the channel mask definition in audio.h, audio_channel_mask_t e.g :
-// Stereo: left, right
-// 5 point 1: front left, front right, front center, low frequency, back left, back right
-// The buffer size is expressed in frame count, a frame being composed of samples for all
-// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by
-// definition
-struct audio_buffer_s {
-    size_t   frameCount;        // number of frames in buffer
-    union {
-        void*       raw;        // raw pointer to start of buffer
-        int32_t*    s32;        // pointer to signed 32 bit data at start of buffer
-        int16_t*    s16;        // pointer to signed 16 bit data at start of buffer
-        uint8_t*    u8;         // pointer to unsigned 8 bit data at start of buffer
-    };
-};
-
-// The buffer_provider_s structure contains functions that can be used
-// by the effect engine process() function to query and release input
-// or output audio buffer.
-// The getBuffer() function is called to retrieve a buffer where data
-// should read from or written to by process() function.
-// The releaseBuffer() function MUST be called when the buffer retrieved
-// with getBuffer() is not needed anymore.
-// The process function should use the buffer provider mechanism to retrieve
-// input or output buffer if the inBuffer or outBuffer passed as argument is NULL
-// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_SET_CONFIG
-// command did not specify an audio buffer.
-
-typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer);
-
-typedef struct buffer_provider_s {
-    buffer_function_t getBuffer;       // retrieve next buffer
-    buffer_function_t releaseBuffer;   // release used buffer
-    void       *cookie;                // for use by client of buffer provider functions
-} buffer_provider_t;
-
-
-// The buffer_config_s structure specifies the input or output audio format
-// to be used by the effect engine. It is part of the effect_config_t
-// structure that defines both input and output buffer configurations and is
-// passed by the EFFECT_CMD_SET_CONFIG or EFFECT_CMD_SET_CONFIG_REVERSE command.
-typedef struct buffer_config_s {
-    audio_buffer_t  buffer;     // buffer for use by process() function if not passed explicitly
-    uint32_t   samplingRate;    // sampling rate
-    uint32_t   channels;        // channel mask (see audio_channel_mask_t in audio.h)
-    buffer_provider_t bufferProvider;   // buffer provider
-    uint8_t    format;          // Audio format (see audio_format_t in audio.h)
-    uint8_t    accessMode;      // read/write or accumulate in buffer (effect_buffer_access_e)
-    uint16_t   mask;            // indicates which of the above fields is valid
-} buffer_config_t;
-
-// Values for "accessMode" field of buffer_config_t:
-//   overwrite, read only, accumulate (read/modify/write)
-enum effect_buffer_access_e {
-    EFFECT_BUFFER_ACCESS_WRITE,
-    EFFECT_BUFFER_ACCESS_READ,
-    EFFECT_BUFFER_ACCESS_ACCUMULATE
-
-};
-
-// feature identifiers for EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS command
-enum effect_feature_e {
-    EFFECT_FEATURE_AUX_CHANNELS, // supports auxiliary channels (e.g. dual mic noise suppressor)
-    EFFECT_FEATURE_CNT
-};
-
-// EFFECT_FEATURE_AUX_CHANNELS feature configuration descriptor. Describe a combination
-// of main and auxiliary channels supported
-typedef struct channel_config_s {
-    audio_channel_mask_t main_channels; // channel mask for main channels
-    audio_channel_mask_t aux_channels;  // channel mask for auxiliary channels
-} channel_config_t;
-
-
-// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field
-// in buffer_config_t must be taken into account when executing the EFFECT_CMD_SET_CONFIG command
-#define EFFECT_CONFIG_BUFFER    0x0001  // buffer field must be taken into account
-#define EFFECT_CONFIG_SMP_RATE  0x0002  // samplingRate field must be taken into account
-#define EFFECT_CONFIG_CHANNELS  0x0004  // channels field must be taken into account
-#define EFFECT_CONFIG_FORMAT    0x0008  // format field must be taken into account
-#define EFFECT_CONFIG_ACC_MODE  0x0010  // accessMode field must be taken into account
-#define EFFECT_CONFIG_PROVIDER  0x0020  // bufferProvider field must be taken into account
-#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \
-                           EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \
-                           EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER)
-
-
-// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_CONFIG
-// command to configure audio parameters and buffers for effect engine input and output.
-typedef struct effect_config_s {
-    buffer_config_t   inputCfg;
-    buffer_config_t   outputCfg;
-} effect_config_t;
-
-
-// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM
-// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command.
-// psize and vsize represent the actual size of parameter and value.
-//
-// NOTE: the start of value field inside the data field is always on a 32 bit boundary:
-//
-//  +-----------+
-//  | status    | sizeof(int)
-//  +-----------+
-//  | psize     | sizeof(int)
-//  +-----------+
-//  | vsize     | sizeof(int)
-//  +-----------+
-//  |           |   |           |
-//  ~ parameter ~   > psize     |
-//  |           |   |           >  ((psize - 1)/sizeof(int) + 1) * sizeof(int)
-//  +-----------+               |
-//  | padding   |               |
-//  +-----------+
-//  |           |   |
-//  ~ value     ~   > vsize
-//  |           |   |
-//  +-----------+
-
-typedef struct effect_param_s {
-    int32_t     status;     // Transaction status (unused for command, used for reply)
-    uint32_t    psize;      // Parameter size
-    uint32_t    vsize;      // Value size
-    char        data[];     // Start of Parameter + Value data
-} effect_param_t;
-
-// Maximum effect_param_t size
-#define EFFECT_PARAM_SIZE_MAX       65536
-
-// structure used by EFFECT_CMD_OFFLOAD command
-typedef struct effect_offload_param_s {
-    bool isOffload;         // true if the playback thread the effect is attached to is offloaded
-    int ioHandle;           // io handle of the playback thread the effect is attached to
-} effect_offload_param_t;
-
-
 /////////////////////////////////////////////////
 //      Effect library interface
 /////////////////////////////////////////////////
diff --git a/include/hardware/ble_advertiser.h b/include/hardware/ble_advertiser.h
new file mode 100644
index 0000000..8abca00
--- /dev/null
+++ b/include/hardware/ble_advertiser.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_BLE_ADVERTISER_H
+#define ANDROID_INCLUDE_BLE_ADVERTISER_H
+
+#include <base/callback_forward.h>
+#include <stdint.h>
+#include <vector>
+#include "bt_common_types.h"
+#include "bt_gatt_types.h"
+
+struct AdvertiseParameters {
+  uint16_t advertising_event_properties;
+  uint32_t min_interval;
+  uint32_t max_interval;
+  uint8_t channel_map;
+  int8_t tx_power;
+  uint8_t primary_advertising_phy;
+  uint8_t secondary_advertising_phy;
+  uint8_t scan_request_notification_enable;
+};
+
+struct PeriodicAdvertisingParameters {
+  uint8_t enable;
+  uint16_t min_interval;
+  uint16_t max_interval;
+  uint16_t periodic_advertising_properties;
+};
+
+class BleAdvertiserInterface {
+ public:
+  virtual ~BleAdvertiserInterface() = default;
+
+  /** Callback invoked when multi-adv operation has completed */
+  using StatusCallback = base::Callback<void(uint8_t /* status */)>;
+  using IdStatusCallback =
+      base::Callback<void(uint8_t /* advertiser_id */, uint8_t /* status */)>;
+  using IdTxPowerStatusCallback =
+      base::Callback<void(uint8_t /* advertiser_id */, int8_t /* tx_power */, uint8_t /* status */)>;
+  using ParametersCallback =
+      base::Callback<void(uint8_t /* status */, int8_t /* tx_power */)>;
+
+  /** Registers an advertiser with the stack */
+  virtual void RegisterAdvertiser(IdStatusCallback) = 0;
+
+  /* Set the parameters as per spec, user manual specified values */
+  virtual void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
+                             ParametersCallback cb) = 0;
+
+  /* Setup the data */
+  virtual void SetData(int advertiser_id, bool set_scan_rsp,
+                       std::vector<uint8_t> data, StatusCallback cb) = 0;
+
+  /* Enable the advertising instance */
+  virtual void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
+                      uint16_t duration, uint8_t maxExtAdvEvents,
+                      StatusCallback timeout_cb) = 0;
+
+  /*  Unregisters an advertiser */
+  virtual void Unregister(uint8_t advertiser_id) = 0;
+
+  virtual void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
+                                AdvertiseParameters params,
+                                std::vector<uint8_t> advertise_data,
+                                std::vector<uint8_t> scan_response_data,
+                                int timeout_s, StatusCallback timeout_cb) = 0;
+
+  /** Start the advertising set. This include registering, setting all
+   * parameters and data, and enabling it. |register_cb| is called when the set
+   * is advertising. |timeout_cb| is called when the timeout_s have passed */
+  virtual void StartAdvertisingSet(
+      IdTxPowerStatusCallback register_cb, AdvertiseParameters params,
+      std::vector<uint8_t> advertise_data,
+      std::vector<uint8_t> scan_response_data,
+      PeriodicAdvertisingParameters periodic_params,
+      std::vector<uint8_t> periodic_data, uint16_t duration,
+      uint8_t maxExtAdvEvents, IdStatusCallback timeout_cb) = 0;
+
+  virtual void SetPeriodicAdvertisingParameters(
+      int advertiser_id, PeriodicAdvertisingParameters parameters,
+      StatusCallback cb) = 0;
+
+  virtual void SetPeriodicAdvertisingData(int advertiser_id,
+                                          std::vector<uint8_t> data,
+                                          StatusCallback cb) = 0;
+
+  virtual void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
+                                            StatusCallback cb) = 0;
+};
+
+#endif /* ANDROID_INCLUDE_BLE_ADVERTISER_H */
diff --git a/include/hardware/ble_scanner.h b/include/hardware/ble_scanner.h
new file mode 100644
index 0000000..c8f9ec2
--- /dev/null
+++ b/include/hardware/ble_scanner.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_BLE_SCANNER_H
+#define ANDROID_INCLUDE_BLE_SCANNER_H
+
+#include <stdint.h>
+#include <vector>
+#include "bt_common_types.h"
+#include "bt_gatt_client.h"
+#include "bt_gatt_types.h"
+
+/** Callback invoked when batchscan reports are obtained */
+typedef void (*batchscan_reports_callback)(int client_if, int status,
+                                           int report_format, int num_records,
+                                           std::vector<uint8_t> data);
+
+/** Callback invoked when batchscan storage threshold limit is crossed */
+typedef void (*batchscan_threshold_callback)(int client_if);
+
+/** Track ADV VSE callback invoked when tracked device is found or lost */
+typedef void (*track_adv_event_callback)(
+    btgatt_track_adv_info_t *p_track_adv_info);
+
+/** Callback for scan results */
+typedef void (*scan_result_callback)(uint16_t event_type, uint8_t addr_type,
+                                     bt_bdaddr_t *bda, uint8_t primary_phy,
+                                     uint8_t secondary_phy,
+                                     uint8_t advertising_sid, int8_t tx_power,
+                                     int8_t rssi, uint16_t periodic_adv_int,
+                                     std::vector<uint8_t> adv_data);
+
+typedef struct {
+  scan_result_callback scan_result_cb;
+  batchscan_reports_callback batchscan_reports_cb;
+  batchscan_threshold_callback batchscan_threshold_cb;
+  track_adv_event_callback track_adv_event_cb;
+} btgatt_scanner_callbacks_t;
+
+class BleScannerInterface {
+ public:
+  virtual ~BleScannerInterface() = default;
+
+  using RegisterCallback =
+      base::Callback<void(uint8_t /* scanner_id */, uint8_t /* status */)>;
+
+  using Callback = base::Callback<void(uint8_t /* status */)>;
+
+  using EnableCallback =
+      base::Callback<void(uint8_t /* action */, uint8_t /* status */)>;
+
+  using FilterParamSetupCallback =
+      base::Callback<void(uint8_t /* avbl_space */, uint8_t /* action_type */,
+                          uint8_t /* status */)>;
+
+  using FilterConfigCallback =
+      base::Callback<void(uint8_t /* filt_type */, uint8_t /* avbl_space */,
+                          uint8_t /* action */, uint8_t /* status */)>;
+
+  /** Registers a scanner with the stack */
+  virtual void RegisterScanner(RegisterCallback) = 0;
+
+  /** Unregister a scanner from the stack */
+  virtual void Unregister(int scanner_id) = 0;
+
+  /** Start or stop LE device scanning */
+  virtual void Scan(bool start) = 0;
+
+  /** Setup scan filter params */
+  virtual void ScanFilterParamSetup(
+      uint8_t client_if, uint8_t action, uint8_t filt_index,
+      std::unique_ptr<btgatt_filt_param_setup_t> filt_param,
+      FilterParamSetupCallback cb) = 0;
+
+  /** Configure a scan filter condition  */
+  virtual void ScanFilterAddRemove(int action, int filt_type, int filt_index,
+                                   int company_id, int company_id_mask,
+                                   const bt_uuid_t *p_uuid,
+                                   const bt_uuid_t *p_uuid_mask,
+                                   const bt_bdaddr_t *bd_addr, char addr_type,
+                                   std::vector<uint8_t> data,
+                                   std::vector<uint8_t> p_mask,
+                                   FilterConfigCallback cb) = 0;
+
+  /** Clear all scan filter conditions for specific filter index*/
+  virtual void ScanFilterClear(int filt_index, FilterConfigCallback cb) = 0;
+
+  /** Enable / disable scan filter feature*/
+  virtual void ScanFilterEnable(bool enable, EnableCallback cb) = 0;
+
+  /** Sets the LE scan interval and window in units of N*0.625 msec */
+  virtual void SetScanParameters(int scan_interval, int scan_window,
+                                 Callback cb) = 0;
+
+  /* Configure the batchscan storage */
+  virtual void BatchscanConfigStorage(int client_if, int batch_scan_full_max,
+                                      int batch_scan_trunc_max,
+                                      int batch_scan_notify_threshold,
+                                      Callback cb) = 0;
+
+  /* Enable batchscan */
+  virtual void BatchscanEnable(int scan_mode, int scan_interval,
+                               int scan_window, int addr_type, int discard_rule,
+                               Callback cb) = 0;
+
+  /* Disable batchscan */
+  virtual void BatchscanDisable(Callback cb) = 0;
+
+  /* Read out batchscan reports */
+  virtual void BatchscanReadReports(int client_if, int scan_mode) = 0;
+
+  using StartSyncCb =
+      base::Callback<void(uint8_t status, uint16_t sync_handle,
+                          uint8_t advertising_sid, uint8_t address_type,
+                          bt_bdaddr_t address, uint8_t phy, uint16_t interval)>;
+  using SyncReportCb =
+      base::Callback<void(uint16_t sync_handle, int8_t tx_power, int8_t rssi,
+                          uint8_t status, std::vector<uint8_t> data)>;
+  using SyncLostCb = base::Callback<void(uint16_t sync_handle)>;
+  virtual void StartSync(uint8_t sid, bt_bdaddr_t address, uint16_t skip,
+                         uint16_t timeout, StartSyncCb start_cb,
+                         SyncReportCb report_cb, SyncLostCb lost_cb) = 0;
+  virtual void StopSync(uint16_t handle) = 0;
+};
+
+#endif /* ANDROID_INCLUDE_BLE_SCANNER_H */
\ No newline at end of file
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index dd5ea8a..5d69ab3 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -44,6 +44,7 @@
 #define BT_PROFILE_HEALTH_ID "health"
 #define BT_PROFILE_SOCKETS_ID "socket"
 #define BT_PROFILE_HIDHOST_ID "hidhost"
+#define BT_PROFILE_HIDDEV_ID "hiddev"
 #define BT_PROFILE_PAN_ID "pan"
 #define BT_PROFILE_MAP_CLIENT_ID "map_client"
 #define BT_PROFILE_SDP_CLIENT_ID "sdp"
@@ -162,6 +163,11 @@
     uint16_t total_trackable_advertisers;
     bool extended_scan_support;
     bool debug_logging_supported;
+    bool le_2m_phy_supported;
+    bool le_coded_phy_supported;
+    bool le_extended_advertising_supported;
+    bool le_periodic_advertising_supported;
+    uint16_t le_maximum_advertising_data_length;
 }bt_local_le_features_t;
 
 /* Bluetooth Adapter and Remote Device property types */
@@ -273,7 +279,7 @@
    uint8_t c256[16]; /* Simple Pairing Hash C-256 */
    uint8_t r256[16]; /* Simple Pairing Randomizer R-256 */
    uint8_t sm_tk[16]; /* Security Manager TK Value */
-   uint8_t le_sc_c[16]; /* LE Secure Connections Random Value */
+   uint8_t le_sc_c[16]; /* LE Secure Connections Confirmation Value */
    uint8_t le_sc_r[16]; /* LE Secure Connections Random Value */
 } bt_out_of_band_data_t;
 
diff --git a/include/hardware/bt_av.h b/include/hardware/bt_av.h
index 9b32216..91ae2ac 100644
--- a/include/hardware/bt_av.h
+++ b/include/hardware/bt_av.h
@@ -17,6 +17,10 @@
 #ifndef ANDROID_INCLUDE_BT_AV_H
 #define ANDROID_INCLUDE_BT_AV_H
 
+#include <vector>
+
+#include <hardware/bluetooth.h>
+
 __BEGIN_DECLS
 
 /* Bluetooth AV connection states */
@@ -34,6 +38,93 @@
     BTAV_AUDIO_STATE_STARTED,
 } btav_audio_state_t;
 
+/*
+ * Enum values for each A2DP supported codec.
+ * There should be a separate entry for each A2DP codec that is supported
+ * for encoding (SRC), and for decoding purpose (SINK).
+ */
+typedef enum {
+  BTAV_A2DP_CODEC_INDEX_SOURCE_MIN = 0,
+
+  // Add an entry for each source codec here.
+  // NOTE: The values should be same as those listed in the following file:
+  //   BluetoothCodecConfig.java
+  BTAV_A2DP_CODEC_INDEX_SOURCE_SBC = 0,
+  BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
+  BTAV_A2DP_CODEC_INDEX_SOURCE_APTX,
+  BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
+  BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC,
+
+  BTAV_A2DP_CODEC_INDEX_SOURCE_MAX,
+
+  BTAV_A2DP_CODEC_INDEX_SINK_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MAX,
+
+  // Add an entry for each sink codec here
+  BTAV_A2DP_CODEC_INDEX_SINK_SBC = BTAV_A2DP_CODEC_INDEX_SINK_MIN,
+
+  BTAV_A2DP_CODEC_INDEX_SINK_MAX,
+
+  BTAV_A2DP_CODEC_INDEX_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MIN,
+  BTAV_A2DP_CODEC_INDEX_MAX = BTAV_A2DP_CODEC_INDEX_SINK_MAX
+} btav_a2dp_codec_index_t;
+
+typedef enum {
+  // Disable the codec.
+  // NOTE: This value can be used only during initialization when
+  // function btav_source_interface_t::init() is called.
+  BTAV_A2DP_CODEC_PRIORITY_DISABLED = -1,
+
+  // Reset the codec priority to its default value.
+  BTAV_A2DP_CODEC_PRIORITY_DEFAULT = 0,
+
+  // Highest codec priority.
+  BTAV_A2DP_CODEC_PRIORITY_HIGHEST = 1000 * 1000
+} btav_a2dp_codec_priority_t;
+
+typedef enum {
+  BTAV_A2DP_CODEC_SAMPLE_RATE_NONE   = 0x0,
+  BTAV_A2DP_CODEC_SAMPLE_RATE_44100  = 0x1 << 0,
+  BTAV_A2DP_CODEC_SAMPLE_RATE_48000  = 0x1 << 1,
+  BTAV_A2DP_CODEC_SAMPLE_RATE_88200  = 0x1 << 2,
+  BTAV_A2DP_CODEC_SAMPLE_RATE_96000  = 0x1 << 3,
+  BTAV_A2DP_CODEC_SAMPLE_RATE_176400 = 0x1 << 4,
+  BTAV_A2DP_CODEC_SAMPLE_RATE_192000 = 0x1 << 5
+} btav_a2dp_codec_sample_rate_t;
+
+typedef enum {
+  BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE = 0x0,
+  BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16   = 0x1 << 0,
+  BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24   = 0x1 << 1,
+  BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32   = 0x1 << 2
+} btav_a2dp_codec_bits_per_sample_t;
+
+typedef enum {
+  BTAV_A2DP_CODEC_CHANNEL_MODE_NONE   = 0x0,
+  BTAV_A2DP_CODEC_CHANNEL_MODE_MONO   = 0x1 << 0,
+  BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO = 0x1 << 1
+} btav_a2dp_codec_channel_mode_t;
+
+/*
+ * Structure for representing codec capability or configuration.
+ * It is used for configuring A2DP codec preference, and for reporting back
+ * current configuration or codec capability.
+ * For codec capability, fields "sample_rate", "bits_per_sample" and
+ * "channel_mode" can contain bit-masks with all supported features.
+ */
+typedef struct {
+  btav_a2dp_codec_index_t codec_type;
+  btav_a2dp_codec_priority_t codec_priority; // Codec selection priority
+                                // relative to other codecs: larger value
+                                // means higher priority. If 0, reset to
+                                // default.
+  btav_a2dp_codec_sample_rate_t sample_rate;
+  btav_a2dp_codec_bits_per_sample_t bits_per_sample;
+  btav_a2dp_codec_channel_mode_t channel_mode;
+  int64_t codec_specific_1;     // Codec-specific value 1
+  int64_t codec_specific_2;     // Codec-specific value 2
+  int64_t codec_specific_3;     // Codec-specific value 3
+  int64_t codec_specific_4;     // Codec-specific value 4
+} btav_a2dp_codec_config_t;
 
 /** Callback for connection state change.
  *  state will have one of the values from btav_connection_state_t
@@ -48,23 +139,39 @@
                                                bt_bdaddr_t *bd_addr);
 
 /** Callback for audio configuration change.
- *  Used only for the A2DP sink interface.
- *  state will have one of the values from btav_audio_state_t
+ *  Used only for the A2DP Source interface.
+ */
+typedef void (* btav_audio_source_config_callback)(
+    btav_a2dp_codec_config_t codec_config,
+    std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities,
+    std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities);
+
+/** Callback for audio configuration change.
+ *  Used only for the A2DP Sink interface.
  *  sample_rate: sample rate in Hz
  *  channel_count: number of channels (1 for mono, 2 for stereo)
  */
-typedef void (* btav_audio_config_callback)(bt_bdaddr_t *bd_addr,
-                                                uint32_t sample_rate,
-                                                uint8_t channel_count);
+typedef void (* btav_audio_sink_config_callback)(bt_bdaddr_t *bd_addr,
+                                                 uint32_t sample_rate,
+                                                 uint8_t channel_count);
 
-/** BT-AV callback structure. */
+/** BT-AV A2DP Source callback structure. */
 typedef struct {
-    /** set to sizeof(btav_callbacks_t) */
+    /** set to sizeof(btav_source_callbacks_t) */
     size_t      size;
     btav_connection_state_callback  connection_state_cb;
     btav_audio_state_callback audio_state_cb;
-    btav_audio_config_callback audio_config_cb;
-} btav_callbacks_t;
+    btav_audio_source_config_callback audio_config_cb;
+} btav_source_callbacks_t;
+
+/** BT-AV A2DP Sink callback structure. */
+typedef struct {
+    /** set to sizeof(btav_sink_callbacks_t) */
+    size_t      size;
+    btav_connection_state_callback  connection_state_cb;
+    btav_audio_state_callback audio_state_cb;
+    btav_audio_sink_config_callback audio_config_cb;
+} btav_sink_callbacks_t;
 
 /**
  * NOTE:
@@ -76,17 +183,43 @@
  *    android_audio_hw library and the Bluetooth stack.
  *
  */
-/** Represents the standard BT-AV interface.
- *  Used for both the A2DP source and sink interfaces.
+
+/** Represents the standard BT-AV A2DP Source interface.
  */
 typedef struct {
 
-    /** set to sizeof(btav_interface_t) */
+    /** set to sizeof(btav_source_interface_t) */
+    size_t          size;
+    /**
+     * Register the BtAv callbacks.
+     */
+    bt_status_t (*init)(btav_source_callbacks_t* callbacks,
+                std::vector<btav_a2dp_codec_config_t> codec_priorities);
+
+    /** connect to headset */
+    bt_status_t (*connect)( bt_bdaddr_t *bd_addr );
+
+    /** dis-connect from headset */
+    bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr );
+
+    /** configure the codecs settings preferences */
+    bt_status_t (*config_codec)(std::vector<btav_a2dp_codec_config_t> codec_preferences);
+
+    /** Closes the interface. */
+    void  (*cleanup)( void );
+
+} btav_source_interface_t;
+
+/** Represents the standard BT-AV A2DP Sink interface.
+ */
+typedef struct {
+
+    /** set to sizeof(btav_sink_interface_t) */
     size_t          size;
     /**
      * Register the BtAv callbacks
      */
-    bt_status_t (*init)( btav_callbacks_t* callbacks );
+    bt_status_t (*init)( btav_sink_callbacks_t* callbacks );
 
     /** connect to headset */
     bt_status_t (*connect)( bt_bdaddr_t *bd_addr );
@@ -102,7 +235,7 @@
 
     /** Sets the audio track gain. */
     void  (*set_audio_track_gain)( float gain );
-} btav_interface_t;
+} btav_sink_interface_t;
 
 __END_DECLS
 
diff --git a/include/hardware/bt_common_types.h b/include/hardware/bt_common_types.h
index 01b5256..cff3072 100644
--- a/include/hardware/bt_common_types.h
+++ b/include/hardware/bt_common_types.h
@@ -70,6 +70,22 @@
      * the characteristic.
      */
     uint8_t             properties;
+    uint16_t            permissions;
 } btgatt_db_element_t;
 
+typedef struct
+{
+    uint16_t feat_seln;
+    uint16_t list_logic_type;
+    uint8_t  filt_logic_type;
+    uint8_t  rssi_high_thres;
+    uint8_t  rssi_low_thres;
+    uint8_t  dely_mode;
+    uint16_t found_timeout;
+    uint16_t lost_timeout;
+    uint8_t  found_timeout_cnt;
+    uint16_t  num_of_tracking_entries;
+} btgatt_filt_param_setup_t;
+
+
 #endif  /* ANDROID_INCLUDE_BT_COMMON_TYPES_H */
diff --git a/include/hardware/bt_gatt.h b/include/hardware/bt_gatt.h
index 42e14c2..393d1a5 100644
--- a/include/hardware/bt_gatt.h
+++ b/include/hardware/bt_gatt.h
@@ -19,6 +19,8 @@
 #define ANDROID_INCLUDE_BT_GATT_H
 
 #include <stdint.h>
+#include "ble_advertiser.h"
+#include "ble_scanner.h"
 #include "bt_gatt_client.h"
 #include "bt_gatt_server.h"
 
@@ -34,6 +36,9 @@
 
     /** GATT Server callbacks */
     const btgatt_server_callbacks_t* server;
+
+    /** LE scanner callbacks */
+    const btgatt_scanner_callbacks_t* scanner;
 } btgatt_callbacks_t;
 
 /** Represents the standard Bluetooth GATT interface. */
@@ -54,6 +59,12 @@
 
     /** Pointer to the GATT server interface methods.*/
     const btgatt_server_interface_t* server;
+
+    /** Pointer to the LE scanner interface methods.*/
+    BleScannerInterface* scanner;
+
+    /** Pointer to the advertiser interface methods.*/
+    BleAdvertiserInterface* advertiser;
 } btgatt_interface_t;
 
 __END_DECLS
diff --git a/include/hardware/bt_gatt_client.h b/include/hardware/bt_gatt_client.h
index e2c8a92..ec8dd16 100644
--- a/include/hardware/bt_gatt_client.h
+++ b/include/hardware/bt_gatt_client.h
@@ -19,6 +19,7 @@
 #define ANDROID_INCLUDE_BT_GATT_CLIENT_H
 
 #include <stdint.h>
+#include <vector>
 #include "bt_gatt_types.h"
 #include "bt_common_types.h"
 
@@ -67,23 +68,6 @@
 
 typedef struct
 {
-    uint8_t  client_if;
-    uint8_t  action;
-    uint8_t  filt_index;
-    uint16_t feat_seln;
-    uint16_t list_logic_type;
-    uint8_t  filt_logic_type;
-    uint8_t  rssi_high_thres;
-    uint8_t  rssi_low_thres;
-    uint8_t  dely_mode;
-    uint16_t found_timeout;
-    uint16_t lost_timeout;
-    uint8_t  found_timeout_cnt;
-    uint16_t  num_of_tracking_entries;
-} btgatt_filt_param_setup_t;
-
-typedef struct
-{
     bt_bdaddr_t        *bda1;
     bt_uuid_t          *uuid1;
     uint16_t            u1;
@@ -118,9 +102,6 @@
 typedef void (*register_client_callback)(int status, int client_if,
                 bt_uuid_t *app_uuid);
 
-/** Callback for scan results */
-typedef void (*scan_result_callback)(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data);
-
 /** GATT open callback invoked in response to open */
 typedef void (*connect_callback)(int conn_id, int status, int client_if, bt_bdaddr_t* bda);
 
@@ -165,36 +146,9 @@
 typedef void (*read_remote_rssi_callback)(int client_if, bt_bdaddr_t* bda,
                                           int rssi, int status);
 
-/**
- * Callback indicating the status of a listen() operation
- */
-typedef void (*listen_callback)(int status, int server_if);
-
 /** Callback invoked when the MTU for a given connection changes */
 typedef void (*configure_mtu_callback)(int conn_id, int status, int mtu);
 
-/** Callback invoked when a scan filter configuration command has completed */
-typedef void (*scan_filter_cfg_callback)(int action, int client_if, int status, int filt_type,
-                                         int avbl_space);
-
-/** Callback invoked when scan param has been added, cleared, or deleted */
-typedef void (*scan_filter_param_callback)(int action, int client_if, int status,
-                                         int avbl_space);
-
-/** Callback invoked when a scan filter configuration command has completed */
-typedef void (*scan_filter_status_callback)(int enable, int client_if, int status);
-
-/** Callback invoked when multi-adv enable operation has completed */
-typedef void (*multi_adv_enable_callback)(int client_if, int status);
-
-/** Callback invoked when multi-adv param update operation has completed */
-typedef void (*multi_adv_update_callback)(int client_if, int status);
-
-/** Callback invoked when multi-adv instance data set operation has completed */
-typedef void (*multi_adv_data_callback)(int client_if, int status);
-
-/** Callback invoked when multi-adv disable operation has completed */
-typedef void (*multi_adv_disable_callback)(int client_if, int status);
 
 /**
  * Callback notifying an application that a remote device connection is currently congested
@@ -202,25 +156,6 @@
  * a further callback is received indicating the congestion status has been cleared.
  */
 typedef void (*congestion_callback)(int conn_id, bool congested);
-/** Callback invoked when batchscan storage config operation has completed */
-typedef void (*batchscan_cfg_storage_callback)(int client_if, int status);
-
-/** Callback invoked when batchscan enable / disable operation has completed */
-typedef void (*batchscan_enable_disable_callback)(int action, int client_if, int status);
-
-/** Callback invoked when batchscan reports are obtained */
-typedef void (*batchscan_reports_callback)(int client_if, int status, int report_format,
-                                           int num_records, int data_len, uint8_t* rep_data);
-
-/** Callback invoked when batchscan storage threshold limit is crossed */
-typedef void (*batchscan_threshold_callback)(int client_if);
-
-/** Track ADV VSE callback invoked when tracked device is found or lost */
-typedef void (*track_adv_event_callback)(btgatt_track_adv_info_t *p_track_adv_info);
-
-/** Callback invoked when scan parameter setup has completed */
-typedef void (*scan_parameter_setup_completed_callback)(int client_if,
-                                                        btgattc_error_t status);
 
 /** GATT get database callback */
 typedef void (*get_gatt_db_callback)(int conn_id, btgatt_db_element_t *db, int count);
@@ -231,9 +166,17 @@
 /** GATT services were added */
 typedef void (*services_added_callback)(int conn_id, btgatt_db_element_t *added, int added_count);
 
+/** Callback invoked when the PHY for a given connection changes */
+typedef void (*phy_updated_callback)(int conn_id, uint8_t tx_phy,
+                                     uint8_t rx_phy, uint8_t status);
+
+/** Callback invoked when the connection parameters for a given connection changes */
+typedef void (*conn_updated_callback)(int conn_id, uint16_t interval,
+                                      uint16_t latency, uint16_t timeout,
+                                      uint8_t status);
+
 typedef struct {
     register_client_callback            register_client_cb;
-    scan_result_callback                scan_result_cb;
     connect_callback                    open_cb;
     disconnect_callback                 close_cb;
     search_complete_callback            search_complete_cb;
@@ -245,25 +188,13 @@
     write_descriptor_callback           write_descriptor_cb;
     execute_write_callback              execute_write_cb;
     read_remote_rssi_callback           read_remote_rssi_cb;
-    listen_callback                     listen_cb;
     configure_mtu_callback              configure_mtu_cb;
-    scan_filter_cfg_callback            scan_filter_cfg_cb;
-    scan_filter_param_callback          scan_filter_param_cb;
-    scan_filter_status_callback         scan_filter_status_cb;
-    multi_adv_enable_callback           multi_adv_enable_cb;
-    multi_adv_update_callback           multi_adv_update_cb;
-    multi_adv_data_callback             multi_adv_data_cb;
-    multi_adv_disable_callback          multi_adv_disable_cb;
     congestion_callback                 congestion_cb;
-    batchscan_cfg_storage_callback      batchscan_cfg_storage_cb;
-    batchscan_enable_disable_callback   batchscan_enb_disable_cb;
-    batchscan_reports_callback          batchscan_reports_cb;
-    batchscan_threshold_callback        batchscan_threshold_cb;
-    track_adv_event_callback            track_adv_event_cb;
-    scan_parameter_setup_completed_callback scan_parameter_setup_completed_cb;
     get_gatt_db_callback                get_gatt_db_cb;
     services_removed_callback           services_removed_cb;
     services_added_callback             services_added_cb;
+    phy_updated_callback                phy_updated_cb;
+    conn_updated_callback               conn_updated_cb;
 } btgatt_client_callbacks_t;
 
 /** Represents the standard BT-GATT client interface. */
@@ -275,20 +206,14 @@
     /** Unregister a client application from the stack */
     bt_status_t (*unregister_client)(int client_if );
 
-    /** Start or stop LE device scanning */
-    bt_status_t (*scan)( bool start );
-
     /** Create a connection to a remote LE or dual-mode device */
-    bt_status_t (*connect)( int client_if, const bt_bdaddr_t *bd_addr,
-                         bool is_direct, int transport );
+    bt_status_t (*connect)(int client_if, const bt_bdaddr_t *bd_addr,
+                           bool is_direct, int transport, int initiating_phys);
 
     /** Disconnect a remote device or cancel a pending connection */
     bt_status_t (*disconnect)( int client_if, const bt_bdaddr_t *bd_addr,
                     int conn_id);
 
-    /** Start or stop advertisements to listen for incoming connections */
-    bt_status_t (*listen)(int client_if, bool start);
-
     /** Clear the attribute cache for a given device */
     bt_status_t (*refresh)( int client_if, const bt_bdaddr_t *bd_addr );
 
@@ -304,16 +229,15 @@
 
     /** Write a remote characteristic */
     bt_status_t (*write_characteristic)(int conn_id, uint16_t handle,
-                    int write_type, int len, int auth_req,
-                    char* p_value);
+                    int write_type, int auth_req,
+                    std::vector<uint8_t> value);
 
     /** Read the descriptor for a given characteristic */
     bt_status_t (*read_descriptor)(int conn_id, uint16_t handle, int auth_req);
 
     /** Write a remote descriptor for a given characteristic */
     bt_status_t (*write_descriptor)( int conn_id, uint16_t handle,
-                    int write_type, int len,
-                    int auth_req, char* p_value);
+                                     int auth_req, std::vector<uint8_t> value);
 
     /** Execute a prepared write operation */
     bt_status_t (*execute_write)(int conn_id, int execute);
@@ -332,34 +256,9 @@
     /** Request RSSI for a given remote device */
     bt_status_t (*read_remote_rssi)( int client_if, const bt_bdaddr_t *bd_addr);
 
-    /** Setup scan filter params */
-    bt_status_t (*scan_filter_param_setup)(btgatt_filt_param_setup_t filt_param);
-
-
-    /** Configure a scan filter condition  */
-    bt_status_t (*scan_filter_add_remove)(int client_if, int action, int filt_type,
-                                   int filt_index, int company_id,
-                                   int company_id_mask, const bt_uuid_t *p_uuid,
-                                   const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
-                                   char addr_type, int data_len, char* p_data, int mask_len,
-                                   char* p_mask);
-
-    /** Clear all scan filter conditions for specific filter index*/
-    bt_status_t (*scan_filter_clear)(int client_if, int filt_index);
-
-    /** Enable / disable scan filter feature*/
-    bt_status_t (*scan_filter_enable)(int client_if, bool enable);
-
     /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */
     int (*get_device_type)( const bt_bdaddr_t *bd_addr );
 
-    /** Set the advertising data or scan response data */
-    bt_status_t (*set_adv_data)(int client_if, bool set_scan_rsp, bool include_name,
-                    bool include_txpower, int min_interval, int max_interval, int appearance,
-                    uint16_t manufacturer_len, char* manufacturer_data,
-                    uint16_t service_data_len, char* service_data,
-                    uint16_t service_uuid_len, char* service_uuid);
-
     /** Configure the MTU for a given connection */
     bt_status_t (*configure_mtu)(int conn_id, int mtu);
 
@@ -367,39 +266,13 @@
     bt_status_t (*conn_parameter_update)(const bt_bdaddr_t *bd_addr, int min_interval,
                     int max_interval, int latency, int timeout);
 
-    /** Sets the LE scan interval and window in units of N*0.625 msec */
-    bt_status_t (*set_scan_parameters)(int client_if, int scan_interval, int scan_window);
+    bt_status_t (*set_preferred_phy)(int conn_id, uint8_t tx_phy,
+                                     uint8_t rx_phy, uint16_t phy_options);
 
-    /* Setup the parameters as per spec, user manual specified values and enable multi ADV */
-    bt_status_t (*multi_adv_enable)(int client_if, int min_interval,int max_interval,int adv_type,
-                 int chnl_map, int tx_power, int timeout_s);
-
-    /* Update the parameters as per spec, user manual specified values and restart multi ADV */
-    bt_status_t (*multi_adv_update)(int client_if, int min_interval,int max_interval,int adv_type,
-                 int chnl_map, int tx_power, int timeout_s);
-
-    /* Setup the data for the specified instance */
-    bt_status_t (*multi_adv_set_inst_data)(int client_if, bool set_scan_rsp, bool include_name,
-                    bool incl_txpower, int appearance, int manufacturer_len,
-                    char* manufacturer_data, int service_data_len,
-                    char* service_data, int service_uuid_len, char* service_uuid);
-
-    /* Disable the multi adv instance */
-    bt_status_t (*multi_adv_disable)(int client_if);
-
-    /* Configure the batchscan storage */
-    bt_status_t (*batchscan_cfg_storage)(int client_if, int batch_scan_full_max,
-        int batch_scan_trunc_max, int batch_scan_notify_threshold);
-
-    /* Enable batchscan */
-    bt_status_t (*batchscan_enb_batch_scan)(int client_if, int scan_mode,
-        int scan_interval, int scan_window, int addr_type, int discard_rule);
-
-    /* Disable batchscan */
-    bt_status_t (*batchscan_dis_batch_scan)(int client_if);
-
-    /* Read out batchscan reports */
-    bt_status_t (*batchscan_read_reports)(int client_if, int scan_mode);
+    bt_status_t (*read_phy)(
+        int conn_id,
+        base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)>
+            cb);
 
     /** Test mode interface */
     bt_status_t (*test_command)( int command, btgatt_test_params_t* params);
diff --git a/include/hardware/bt_gatt_server.h b/include/hardware/bt_gatt_server.h
index 0d6cc1e..36259a1 100644
--- a/include/hardware/bt_gatt_server.h
+++ b/include/hardware/bt_gatt_server.h
@@ -19,6 +19,7 @@
 #define ANDROID_INCLUDE_BT_GATT_SERVER_H
 
 #include <stdint.h>
+#include <vector>
 
 #include "bt_gatt_types.h"
 
@@ -53,23 +54,7 @@
 
 /** Callback invoked in response to create_service */
 typedef void (*service_added_callback)(int status, int server_if,
-                btgatt_srvc_id_t *srvc_id, int srvc_handle);
-
-/** Callback indicating that an included service has been added to a service */
-typedef void (*included_service_added_callback)(int status, int server_if,
-                int srvc_handle, int incl_srvc_handle);
-
-/** Callback invoked when a characteristic has been added to a service */
-typedef void (*characteristic_added_callback)(int status, int server_if,
-                bt_uuid_t *uuid, int srvc_handle, int char_handle);
-
-/** Callback invoked when a descriptor has been added to a characteristic */
-typedef void (*descriptor_added_callback)(int status, int server_if,
-                bt_uuid_t *uuid, int srvc_handle, int descr_handle);
-
-/** Callback invoked in response to start_service */
-typedef void (*service_started_callback)(int status, int server_if,
-                                         int srvc_handle);
+                                       std::vector<btgatt_db_element_t> service);
 
 /** Callback invoked in response to stop_service */
 typedef void (*service_stopped_callback)(int status, int server_if,
@@ -91,8 +76,8 @@
  * characteristic or descriptor.
  */
 typedef void (*request_write_callback)(int conn_id, int trans_id, bt_bdaddr_t *bda,
-                                       int attr_handle, int offset, int length,
-                                       bool need_rsp, bool is_prep, uint8_t* value);
+                                       int attr_handle, int offset, bool need_rsp,
+                                       bool is_prep, std::vector<uint8_t> value);
 
 /** Callback invoked when a previously prepared write is to be executed */
 typedef void (*request_exec_write_callback)(int conn_id, int trans_id,
@@ -120,23 +105,31 @@
 /** Callback invoked when the MTU for a given connection changes */
 typedef void (*mtu_changed_callback)(int conn_id, int mtu);
 
+/** Callback invoked when the PHY for a given connection changes */
+typedef void (*phy_updated_callback)(int conn_id, uint8_t tx_phy,
+                                     uint8_t rx_phy, uint8_t status);
+
+/** Callback invoked when the connection parameters for a given connection changes */
+typedef void (*conn_updated_callback)(int conn_id, uint16_t interval,
+                                      uint16_t latency, uint16_t timeout,
+                                      uint8_t status);
 typedef struct {
     register_server_callback        register_server_cb;
     connection_callback             connection_cb;
     service_added_callback          service_added_cb;
-    included_service_added_callback included_service_added_cb;
-    characteristic_added_callback   characteristic_added_cb;
-    descriptor_added_callback       descriptor_added_cb;
-    service_started_callback        service_started_cb;
     service_stopped_callback        service_stopped_cb;
     service_deleted_callback        service_deleted_cb;
-    request_read_callback           request_read_cb;
-    request_write_callback          request_write_cb;
+    request_read_callback           request_read_characteristic_cb;
+    request_read_callback           request_read_descriptor_cb;
+    request_write_callback          request_write_characteristic_cb;
+    request_write_callback          request_write_descriptor_cb;
     request_exec_write_callback     request_exec_write_cb;
     response_confirmation_callback  response_confirmation_cb;
     indication_sent_callback        indication_sent_cb;
     congestion_callback             congestion_cb;
     mtu_changed_callback            mtu_changed_cb;
+    phy_updated_callback            phy_updated_cb;
+    conn_updated_callback           conn_updated_cb;
 } btgatt_server_callbacks_t;
 
 /** Represents the standard BT-GATT server interface. */
@@ -156,23 +149,7 @@
                     int conn_id );
 
     /** Create a new service */
-    bt_status_t (*add_service)( int server_if, btgatt_srvc_id_t *srvc_id, int num_handles);
-
-    /** Assign an included service to it's parent service */
-    bt_status_t (*add_included_service)( int server_if, int service_handle, int included_handle);
-
-    /** Add a characteristic to a service */
-    bt_status_t (*add_characteristic)( int server_if,
-                    int service_handle, bt_uuid_t *uuid,
-                    int properties, int permissions);
-
-    /** Add a descriptor to a given service */
-    bt_status_t (*add_descriptor)(int server_if, int service_handle,
-                                  bt_uuid_t *uuid, int permissions);
-
-    /** Starts a local service */
-    bt_status_t (*start_service)(int server_if, int service_handle,
-                                 int transport);
+    bt_status_t (*add_service)(int server_if, std::vector<btgatt_db_element_t> service);
 
     /** Stops a local service */
     bt_status_t (*stop_service)(int server_if, int service_handle);
@@ -182,13 +159,21 @@
 
     /** Send value indication to a remote device */
     bt_status_t (*send_indication)(int server_if, int attribute_handle,
-                                   int conn_id, int len, int confirm,
-                                   char* p_value);
+                                   int conn_id, int confirm,
+                                   std::vector<uint8_t> value);
 
     /** Send a response to a read/write operation */
     bt_status_t (*send_response)(int conn_id, int trans_id,
                                  int status, btgatt_response_t *response);
 
+    bt_status_t (*set_preferred_phy)(int conn_id, uint8_t tx_phy,
+                                     uint8_t rx_phy, uint16_t phy_options);
+
+    bt_status_t (*read_phy)(
+        int conn_id,
+        base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)>
+            cb);
+
 } btgatt_server_interface_t;
 
 __END_DECLS
diff --git a/include/hardware/bt_hd.h b/include/hardware/bt_hd.h
new file mode 100644
index 0000000..263f29f
--- /dev/null
+++ b/include/hardware/bt_hd.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_BT_HD_H
+#define ANDROID_INCLUDE_BT_HD_H
+
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+typedef enum
+{
+    BTHD_REPORT_TYPE_OTHER = 0,
+    BTHD_REPORT_TYPE_INPUT,
+    BTHD_REPORT_TYPE_OUTPUT,
+    BTHD_REPORT_TYPE_FEATURE,
+    BTHD_REPORT_TYPE_INTRDATA // special value for reports to be sent on INTR (INPUT is assumed)
+} bthd_report_type_t;
+
+typedef enum
+{
+    BTHD_APP_STATE_NOT_REGISTERED,
+    BTHD_APP_STATE_REGISTERED
+} bthd_application_state_t;
+
+typedef enum
+{
+    BTHD_CONN_STATE_CONNECTED,
+    BTHD_CONN_STATE_CONNECTING,
+    BTHD_CONN_STATE_DISCONNECTED,
+    BTHD_CONN_STATE_DISCONNECTING,
+    BTHD_CONN_STATE_UNKNOWN
+} bthd_connection_state_t;
+
+typedef struct
+{
+    const char      *name;
+    const char      *description;
+    const char      *provider;
+    uint8_t         subclass;
+    uint8_t         *desc_list;
+    int             desc_list_len;
+} bthd_app_param_t;
+
+typedef struct
+{
+    uint8_t  service_type;
+    uint32_t token_rate;
+    uint32_t token_bucket_size;
+    uint32_t peak_bandwidth;
+    uint32_t access_latency;
+    uint32_t delay_variation;
+} bthd_qos_param_t;
+
+typedef void (* bthd_application_state_callback)(bt_bdaddr_t *bd_addr, bthd_application_state_t state);
+typedef void (* bthd_connection_state_callback)(bt_bdaddr_t *bd_addr, bthd_connection_state_t state);
+typedef void (* bthd_get_report_callback)(uint8_t type, uint8_t id, uint16_t buffer_size);
+typedef void (* bthd_set_report_callback)(uint8_t type, uint8_t id, uint16_t len, uint8_t *p_data);
+typedef void (* bthd_set_protocol_callback)(uint8_t protocol);
+typedef void (* bthd_intr_data_callback)(uint8_t report_id, uint16_t len, uint8_t *p_data);
+typedef void (* bthd_vc_unplug_callback)(void);
+
+/** BT-HD callbacks */
+typedef struct {
+    size_t      size;
+
+    bthd_application_state_callback application_state_cb;
+    bthd_connection_state_callback  connection_state_cb;
+    bthd_get_report_callback        get_report_cb;
+    bthd_set_report_callback        set_report_cb;
+    bthd_set_protocol_callback      set_protocol_cb;
+    bthd_intr_data_callback         intr_data_cb;
+    bthd_vc_unplug_callback         vc_unplug_cb;
+} bthd_callbacks_t;
+
+/** BT-HD interface */
+typedef struct {
+
+    size_t          size;
+
+    /** init interface and register callbacks */
+    bt_status_t (*init)(bthd_callbacks_t* callbacks);
+
+    /** close interface */
+    void  (*cleanup)(void);
+
+    /** register application */
+    bt_status_t (*register_app)(bthd_app_param_t *app_param, bthd_qos_param_t *in_qos,
+                                            bthd_qos_param_t *out_qos);
+
+    /** unregister application */
+    bt_status_t (*unregister_app)(void);
+
+    /** connects to host with virtual cable */
+    bt_status_t (*connect)(bt_bdaddr_t *bd_addr);
+
+    /** disconnects from currently connected host */
+    bt_status_t (*disconnect)(void);
+
+    /** send report */
+    bt_status_t (*send_report)(bthd_report_type_t type, uint8_t id, uint16_t len, uint8_t *p_data);
+
+    /** notifies error for invalid SET_REPORT */
+    bt_status_t (*report_error)(uint8_t error);
+
+    /** send Virtual Cable Unplug  */
+    bt_status_t (*virtual_cable_unplug)(void);
+
+} bthd_interface_t;
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_BT_HD_H */
+
diff --git a/include/hardware/bt_hf.h b/include/hardware/bt_hf.h
index 0a77675..892fbdb 100644
--- a/include/hardware/bt_hf.h
+++ b/include/hardware/bt_hf.h
@@ -252,7 +252,7 @@
     /**
      * Register the BtHf callbacks
      */
-    bt_status_t (*init)( bthf_callbacks_t* callbacks, int max_hf_clients);
+    bt_status_t (*init)( bthf_callbacks_t* callbacks, int max_hf_clients, bool inband_ringing_supported);
 
     /** connect to headset */
     bt_status_t (*connect)( bt_bdaddr_t *bd_addr );
@@ -295,7 +295,7 @@
      */
     bt_status_t (*at_response) (bthf_at_response_t response_code, int error_code, bt_bdaddr_t *bd_addr );
 
-    /** response for CLCC command 
+    /** response for CLCC command
      *  Can be iteratively called for each call index
      *  Call index of 0 will be treated as NULL termination (Completes response)
      */
@@ -305,7 +305,7 @@
                                 bthf_call_addrtype_t type, bt_bdaddr_t *bd_addr );
 
     /** notify of a call state change
-     *  Each update notifies 
+     *  Each update notifies
      *    1. Number of active/held/ringing calls
      *    2. call_state: This denotes the state change that triggered this msg
      *                   This will take one of the values from BtHfCallState
@@ -317,7 +317,7 @@
     /** Closes the interface. */
     void  (*cleanup)( void );
 
-    /** configureation for the SCO codec */
+    /** configuration for the SCO codec */
     bt_status_t (*configure_wbs)( bt_bdaddr_t *bd_addr ,bthf_wbs_config_t config );
 
     /** Response for HF Indicator change (+BIND) */
diff --git a/include/hardware/bt_hf_client.h b/include/hardware/bt_hf_client.h
index 8acf1b2..b728be3 100644
--- a/include/hardware/bt_hf_client.h
+++ b/include/hardware/bt_hf_client.h
@@ -167,104 +167,120 @@
  *  state will have one of the values from BtHfConnectionState
  *  peer/chld_features are valid only for BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED state
  */
-typedef void (* bthf_client_connection_state_callback)(bthf_client_connection_state_t state,
+typedef void (* bthf_client_connection_state_callback)(const bt_bdaddr_t *bd_addr,
+                                                       bthf_client_connection_state_t state,
                                                        unsigned int peer_feat,
-                                                       unsigned int chld_feat,
-                                                       bt_bdaddr_t *bd_addr);
+                                                       unsigned int chld_feat);
 
 /** Callback for audio connection state change.
  *  state will have one of the values from BtHfAudioState
  */
-typedef void (* bthf_client_audio_state_callback)(bthf_client_audio_state_t state,
-                                                  bt_bdaddr_t *bd_addr);
+typedef void (* bthf_client_audio_state_callback)(const bt_bdaddr_t *bd_addr,
+                                                  bthf_client_audio_state_t state);
 
 /** Callback for VR connection state change.
  *  state will have one of the values from BtHfVRState
  */
-typedef void (* bthf_client_vr_cmd_callback)(bthf_client_vr_state_t state);
+typedef void (* bthf_client_vr_cmd_callback)(const bt_bdaddr_t *bd_addr, bthf_client_vr_state_t state);
 
 /** Callback for network state change
  */
-typedef void (* bthf_client_network_state_callback) (bthf_client_network_state_t state);
+typedef void (* bthf_client_network_state_callback) (const bt_bdaddr_t *bd_addr,
+                                                     bthf_client_network_state_t state);
 
 /** Callback for network roaming status change
  */
-typedef void (* bthf_client_network_roaming_callback) (bthf_client_service_type_t type);
+typedef void (* bthf_client_network_roaming_callback) (const bt_bdaddr_t *bd_addr,
+                                                       bthf_client_service_type_t type);
 
 /** Callback for signal strength indication
  */
-typedef void (* bthf_client_network_signal_callback) (int signal_strength);
+typedef void (* bthf_client_network_signal_callback) (const bt_bdaddr_t *bd_addr,
+                                                      int signal_strength);
 
 /** Callback for battery level indication
  */
-typedef void (* bthf_client_battery_level_callback) (int battery_level);
+typedef void (* bthf_client_battery_level_callback) (const bt_bdaddr_t *bd_addr,
+                                                     int battery_level);
 
 /** Callback for current operator name
  */
-typedef void (* bthf_client_current_operator_callback) (const char *name);
+typedef void (* bthf_client_current_operator_callback) (const bt_bdaddr_t *bd_addr,
+                                                        const char *name);
 
 /** Callback for call indicator
  */
-typedef void (* bthf_client_call_callback) (bthf_client_call_t call);
+typedef void (* bthf_client_call_callback) (const bt_bdaddr_t *bd_addr, bthf_client_call_t call);
 
 /** Callback for callsetup indicator
  */
-typedef void (* bthf_client_callsetup_callback) (bthf_client_callsetup_t callsetup);
+typedef void (* bthf_client_callsetup_callback) (const bt_bdaddr_t *bd_addr,
+                                                 bthf_client_callsetup_t callsetup);
 
 /** Callback for callheld indicator
  */
-typedef void (* bthf_client_callheld_callback) (bthf_client_callheld_t callheld);
+typedef void (* bthf_client_callheld_callback) (const bt_bdaddr_t *bd_addr,
+                                                bthf_client_callheld_t callheld);
 
 /** Callback for response and hold
  */
-typedef void (* bthf_client_resp_and_hold_callback) (bthf_client_resp_and_hold_t resp_and_hold);
+typedef void (* bthf_client_resp_and_hold_callback) (const bt_bdaddr_t *bd_addr,
+                                                     bthf_client_resp_and_hold_t resp_and_hold);
 
 /** Callback for Calling Line Identification notification
  *  Will be called only when there is an incoming call and number is provided.
  */
-typedef void (* bthf_client_clip_callback) (const char *number);
+typedef void (* bthf_client_clip_callback) (const bt_bdaddr_t *bd_addr, const char *number);
 
 /**
  * Callback for Call Waiting notification
  */
-typedef void (* bthf_client_call_waiting_callback) (const char *number);
+typedef void (* bthf_client_call_waiting_callback) (const bt_bdaddr_t *bd_addr, const char *number);
 
 /**
  *  Callback for listing current calls. Can be called multiple time.
  *  If number is unknown NULL is passed.
  */
-typedef void (*bthf_client_current_calls) (int index, bthf_client_call_direction_t dir,
+typedef void (*bthf_client_current_calls) (const bt_bdaddr_t *bd_addr, int index,
+                                           bthf_client_call_direction_t dir,
                                            bthf_client_call_state_t state,
                                            bthf_client_call_mpty_type_t mpty,
                                            const char *number);
 
 /** Callback for audio volume change
  */
-typedef void (*bthf_client_volume_change_callback) (bthf_client_volume_type_t type, int volume);
+typedef void (*bthf_client_volume_change_callback) (const bt_bdaddr_t *bd_addr,
+                                                    bthf_client_volume_type_t type,
+                                                    int volume);
 
 /** Callback for command complete event
  *  cme is valid only for BTHF_CLIENT_CMD_COMPLETE_ERROR_CME type
  */
-typedef void (*bthf_client_cmd_complete_callback) (bthf_client_cmd_complete_t type, int cme);
+typedef void (*bthf_client_cmd_complete_callback) (const bt_bdaddr_t *bd_addr,
+                                                   bthf_client_cmd_complete_t type,
+                                                   int cme);
 
 /** Callback for subscriber information
  */
-typedef void (* bthf_client_subscriber_info_callback) (const char *name,
+typedef void (* bthf_client_subscriber_info_callback) (const bt_bdaddr_t *bd_addr,
+                                                       const char *name,
                                                        bthf_client_subscriber_service_type_t type);
 
 /** Callback for in-band ring tone settings
  */
-typedef void (* bthf_client_in_band_ring_tone_callback) (bthf_client_in_band_ring_state_t state);
+typedef void (* bthf_client_in_band_ring_tone_callback) (const bt_bdaddr_t *bd_addr,
+                                                         bthf_client_in_band_ring_state_t state);
 
 /**
  * Callback for requested number from AG
  */
-typedef void (* bthf_client_last_voice_tag_number_callback) (const char *number);
+typedef void (* bthf_client_last_voice_tag_number_callback) (const bt_bdaddr_t *bd_addr,
+                                                             const char *number);
 
 /**
  * Callback for sending ring indication to app
  */
-typedef void (* bthf_client_ring_indication_callback) (void);
+typedef void (* bthf_client_ring_indication_callback) (const bt_bdaddr_t *bd_addr);
 
 /** BT-HF callback structure. */
 typedef struct {
@@ -307,55 +323,59 @@
     bt_status_t (*connect)(bt_bdaddr_t *bd_addr);
 
     /** disconnect from audio gateway */
-    bt_status_t (*disconnect)(bt_bdaddr_t *bd_addr);
+    bt_status_t (*disconnect)(const bt_bdaddr_t *bd_addr);
 
     /** create an audio connection */
-    bt_status_t (*connect_audio)(bt_bdaddr_t *bd_addr);
+    bt_status_t (*connect_audio)(const bt_bdaddr_t *bd_addr);
 
     /** close the audio connection */
-    bt_status_t (*disconnect_audio)(bt_bdaddr_t *bd_addr);
+    bt_status_t (*disconnect_audio)(const bt_bdaddr_t *bd_addr);
 
     /** start voice recognition */
-    bt_status_t (*start_voice_recognition)(void);
+    bt_status_t (*start_voice_recognition)(const bt_bdaddr_t *bd_addr);
 
     /** stop voice recognition */
-    bt_status_t (*stop_voice_recognition)(void);
+    bt_status_t (*stop_voice_recognition)(const bt_bdaddr_t *bd_addr);
 
     /** volume control */
-    bt_status_t (*volume_control) (bthf_client_volume_type_t type, int volume);
+    bt_status_t (*volume_control) (const bt_bdaddr_t *bd_addr,
+                                   bthf_client_volume_type_t type,
+                                   int volume);
 
     /** place a call with number a number
      * if number is NULL last called number is called (aka re-dial)*/
-    bt_status_t (*dial) (const char *number);
+    bt_status_t (*dial) (const bt_bdaddr_t *bd_addr, const char *number);
 
     /** place a call with number specified by location (speed dial) */
-    bt_status_t (*dial_memory) (int location);
+    bt_status_t (*dial_memory) (const bt_bdaddr_t *bd_addr, int location);
 
     /** perform specified call related action
      * idx is limited only for enhanced call control related action
      */
-    bt_status_t (*handle_call_action) (bthf_client_call_action_t action, int idx);
+    bt_status_t (*handle_call_action) (const bt_bdaddr_t *bd_addr,
+                                       bthf_client_call_action_t action,
+                                       int idx);
 
     /** query list of current calls */
-    bt_status_t (*query_current_calls) (void);
+    bt_status_t (*query_current_calls) (const bt_bdaddr_t *bd_addr);
 
     /** query name of current selected operator */
-    bt_status_t (*query_current_operator_name) (void);
+    bt_status_t (*query_current_operator_name) (const bt_bdaddr_t *bd_addr);
 
     /** Retrieve subscriber information */
-    bt_status_t (*retrieve_subscriber_info) (void);
+    bt_status_t (*retrieve_subscriber_info) (const bt_bdaddr_t *bd_addr);
 
     /** Send DTMF code*/
-    bt_status_t (*send_dtmf) (char code);
+    bt_status_t (*send_dtmf) (const bt_bdaddr_t *bd_addr, char code);
 
     /** Request a phone number from AG corresponding to last voice tag recorded */
-    bt_status_t (*request_last_voice_tag_number) (void);
+    bt_status_t (*request_last_voice_tag_number) (const bt_bdaddr_t *bd_addr);
 
     /** Closes the interface. */
     void (*cleanup)(void);
 
     /** Send AT Command. */
-    bt_status_t (*send_at_cmd) (int cmd, int val1, int val2, const char *arg);
+    bt_status_t (*send_at_cmd) (const bt_bdaddr_t *bd_addr, int cmd, int val1, int val2, const char *arg);
 } bthf_client_interface_t;
 
 __END_DECLS
diff --git a/include/hardware/bt_rc.h b/include/hardware/bt_rc.h
index 1e2c293..ee99d91 100644
--- a/include/hardware/bt_rc.h
+++ b/include/hardware/bt_rc.h
@@ -19,17 +19,69 @@
 
 __BEGIN_DECLS
 
+/* Change this macro to use multiple RC */
+#define BT_RC_NUM_APP 1
+
 /* Macros */
-#define BTRC_MAX_ATTR_STR_LEN       255
+#define BTRC_MAX_ATTR_STR_LEN       (1 << 16)
 #define BTRC_UID_SIZE               8
 #define BTRC_MAX_APP_SETTINGS       8
 #define BTRC_MAX_FOLDER_DEPTH       4
 #define BTRC_MAX_APP_ATTR_SIZE      16
-#define BTRC_MAX_ELEM_ATTR_SIZE     7
+#define BTRC_MAX_ELEM_ATTR_SIZE     8
+#define BTRC_FEATURE_BIT_MASK_SIZE 16
+
+/* Macros for valid scopes in get_folder_items */
+#define BTRC_SCOPE_PLAYER_LIST  0x00 /* Media Player List */
+#define BTRC_SCOPE_FILE_SYSTEM  0x01 /* Virtual File System */
+#define BTRC_SCOPE_SEARCH  0x02 /* Search */
+#define BTRC_SCOPE_NOW_PLAYING   0x03 /* Now Playing */
+
+/* Macros for supported character encoding */
+#define BTRC_CHARSET_ID_UTF8  0x006A
+
+/* Macros for item types */
+#define BTRC_ITEM_PLAYER  0x01 /* Media Player */
+#define BTRC_ITEM_FOLDER  0x02 /* Folder */
+#define BTRC_ITEM_MEDIA   0x03 /* Media File */
+
+/* Macros for media attribute IDs */
+#define BTRC_MEDIA_ATTR_ID_INVALID               -1
+#define BTRC_MEDIA_ATTR_ID_TITLE                 0x00000001
+#define BTRC_MEDIA_ATTR_ID_ARTIST                0x00000002
+#define BTRC_MEDIA_ATTR_ID_ALBUM                 0x00000003
+#define BTRC_MEDIA_ATTR_ID_TRACK_NUM             0x00000004
+#define BTRC_MEDIA_ATTR_ID_NUM_TRACKS            0x00000005
+#define BTRC_MEDIA_ATTR_ID_GENRE                 0x00000006
+#define BTRC_MEDIA_ATTR_ID_PLAYING_TIME          0x00000007        /* in miliseconds */
+
+/* Macros for folder types */
+#define BTRC_FOLDER_TYPE_MIXED      0x00
+#define BTRC_FOLDER_TYPE_TITLES     0x01
+#define BTRC_FOLDER_TYPE_ALBUMS     0x02
+#define BTRC_FOLDER_TYPE_ARTISTS    0x03
+#define BTRC_FOLDER_TYPE_GENRES     0x04
+#define BTRC_FOLDER_TYPE_PLAYLISTS  0x05
+#define BTRC_FOLDER_TYPE_YEARS      0x06
+
+/* Macros for media types */
+#define BTRC_MEDIA_TYPE_AUDIO  0x00 /* audio */
+#define BTRC_MEDIA_TYPE_VIDEO  0x01 /* video */
+
+/* Macros for num attributes */
+#define BTRC_NUM_ATTR_NONE 0xFF /* No attributes required */
+#define BTRC_NUM_ATTR_ALL  0X00 /* All attributes required */
+
+#define BTRC_HANDLE_NONE 0xFF
 
 typedef uint8_t btrc_uid_t[BTRC_UID_SIZE];
 
 typedef enum {
+    BTRC_CONNECTION_STATE_DISCONNECTED = 0,
+    BTRC_CONNECTION_STATE_CONNECTED
+} btrc_connection_state_t;
+
+typedef enum {
     BTRC_FEAT_NONE = 0x00,    /* AVRCP 1.0 */
     BTRC_FEAT_METADATA = 0x01,    /* AVRCP 1.3 */
     BTRC_FEAT_ABSOLUTE_VOLUME = 0x02,    /* Supports TG role and volume sync */
@@ -52,6 +104,11 @@
     BTRC_EVT_TRACK_REACHED_START = 0x04,
     BTRC_EVT_PLAY_POS_CHANGED = 0x05,
     BTRC_EVT_APP_SETTINGS_CHANGED = 0x08,
+    BTRC_EVT_NOW_PLAYING_CONTENT_CHANGED = 0x09,
+    BTRC_EVT_AVAL_PLAYER_CHANGE = 0x0a,
+    BTRC_EVT_ADDR_PLAYER_CHANGE = 0x0b,
+    BTRC_EVT_UIDS_CHANGED = 0x0c,
+    BTRC_EVT_VOL_CHANGED = 0x0d,
 } btrc_event_id_t;
 
 typedef enum {
@@ -94,10 +151,33 @@
     BTRC_STS_BAD_PARAM      = 0x01, /* Invalid parameter */
     BTRC_STS_NOT_FOUND      = 0x02, /* Specified parameter is wrong or not found */
     BTRC_STS_INTERNAL_ERR   = 0x03, /* Internal Error */
-    BTRC_STS_NO_ERROR       = 0x04  /* Operation Success */
+    BTRC_STS_NO_ERROR       = 0x04, /* Operation Success */
+    BTRC_STS_UID_CHANGED    = 0x05, /* UIDs changed */
+    BTRC_STS_RESERVED       = 0x06, /* Reserved */
+    BTRC_STS_INV_DIRN       = 0x07, /* Invalid direction */
+    BTRC_STS_INV_DIRECTORY  = 0x08, /* Invalid directory */
+    BTRC_STS_INV_ITEM       = 0x09, /* Invalid Item */
+    BTRC_STS_INV_SCOPE      = 0x0a, /* Invalid scope */
+    BTRC_STS_INV_RANGE      = 0x0b, /* Invalid range */
+    BTRC_STS_DIRECTORY      = 0x0c, /* UID is a directory */
+    BTRC_STS_MEDIA_IN_USE   = 0x0d, /* Media in use */
+    BTRC_STS_PLAY_LIST_FULL = 0x0e, /* Playing list full */
+    BTRC_STS_SRCH_NOT_SPRTD = 0x0f, /* Search not supported */
+    BTRC_STS_SRCH_IN_PROG   = 0x10, /* Search in progress */
+    BTRC_STS_INV_PLAYER     = 0x11, /* Invalid player */
+    BTRC_STS_PLAY_NOT_BROW  = 0x12, /* Player not browsable */
+    BTRC_STS_PLAY_NOT_ADDR  = 0x13, /* Player not addressed */
+    BTRC_STS_INV_RESULTS    = 0x14, /* Invalid results */
+    BTRC_STS_NO_AVBL_PLAY   = 0x15, /* No available players */
+    BTRC_STS_ADDR_PLAY_CHGD = 0x16, /* Addressed player changed */
 } btrc_status_t;
 
 typedef struct {
+    uint16_t player_id;
+    uint16_t uid_counter;
+} btrc_addr_player_changed_t;
+
+typedef struct {
     uint8_t num_attr;
     uint8_t attr_ids[BTRC_MAX_APP_SETTINGS];
     uint8_t attr_values[BTRC_MAX_APP_SETTINGS];
@@ -133,12 +213,25 @@
     uint8_t  attr_count;
 } btrc_getfolderitem_t;
 
+typedef struct {
+    uint16_t type;
+    uint16_t uid_counter;
+} btrc_uids_changed_t;
+
+typedef struct {
+    uint16_t type;
+} btrc_now_playing_changed_t;
+
 typedef union
 {
     btrc_play_status_t play_status;
     btrc_uid_t track; /* queue position in NowPlaying */
     uint32_t song_pos;
+    uint16_t uid_counter;
     btrc_player_settings_t player_setting;
+    btrc_addr_player_changed_t addr_player_changed;
+    btrc_uids_changed_t uids_changed;
+    btrc_now_playing_changed_t now_playing_changed;
 } btrc_register_notification_t;
 
 typedef struct {
@@ -151,55 +244,141 @@
     uint8_t text[BTRC_MAX_ATTR_STR_LEN];
 } btrc_element_attr_val_t;
 
+typedef struct {
+    uint16_t  player_id;
+    uint8_t   major_type;
+    uint32_t  sub_type;
+    uint8_t   play_status;
+    uint8_t   features[BTRC_FEATURE_BIT_MASK_SIZE];
+    uint16_t  charset_id;
+    uint8_t   name[BTRC_MAX_ATTR_STR_LEN];
+} btrc_item_player_t;
+
+typedef struct {
+    uint8_t   uid[BTRC_UID_SIZE];
+    uint8_t   type;
+    uint8_t   playable;
+    uint16_t  charset_id;
+    uint8_t   name[BTRC_MAX_ATTR_STR_LEN];
+} btrc_item_folder_t;
+
+typedef struct {
+    uint8_t  uid[BTRC_UID_SIZE];
+    uint8_t  type;
+    uint16_t charset_id;
+    uint8_t  name[BTRC_MAX_ATTR_STR_LEN];
+    int      num_attrs;
+    btrc_element_attr_val_t* p_attrs;
+} btrc_item_media_t;
+
+typedef struct {
+    uint8_t item_type;
+    union
+    {
+        btrc_item_player_t player;
+        btrc_item_folder_t folder;
+        btrc_item_media_t  media;
+    };
+} btrc_folder_items_t;
+
+typedef struct {
+    uint16_t  str_len;
+    uint8_t   p_str[BTRC_MAX_ATTR_STR_LEN];
+} btrc_br_folder_name_t;
+
 /** Callback for the controller's supported feautres */
 typedef void (* btrc_remote_features_callback)(bt_bdaddr_t *bd_addr,
                                                       btrc_remote_features_t features);
 
 /** Callback for play status request */
-typedef void (* btrc_get_play_status_callback)();
+typedef void (* btrc_get_play_status_callback)(bt_bdaddr_t *bd_addr);
 
 /** Callback for list player application attributes (Shuffle, Repeat,...) */
-typedef void (* btrc_list_player_app_attr_callback)();
+typedef void (* btrc_list_player_app_attr_callback)(bt_bdaddr_t *bd_addr);
 
 /** Callback for list player application attributes (Shuffle, Repeat,...) */
-typedef void (* btrc_list_player_app_values_callback)(btrc_player_attr_t attr_id);
+typedef void (* btrc_list_player_app_values_callback)(btrc_player_attr_t attr_id,
+    bt_bdaddr_t *bd_addr);
 
 /** Callback for getting the current player application settings value
 **  num_attr: specifies the number of attribute ids contained in p_attrs
 */
-typedef void (* btrc_get_player_app_value_callback) (uint8_t num_attr, btrc_player_attr_t *p_attrs);
+typedef void (* btrc_get_player_app_value_callback) (uint8_t num_attr,
+    btrc_player_attr_t *p_attrs, bt_bdaddr_t *bd_addr);
 
 /** Callback for getting the player application settings attributes' text
 **  num_attr: specifies the number of attribute ids contained in p_attrs
 */
-typedef void (* btrc_get_player_app_attrs_text_callback) (uint8_t num_attr, btrc_player_attr_t *p_attrs);
+typedef void (* btrc_get_player_app_attrs_text_callback) (uint8_t num_attr,
+    btrc_player_attr_t *p_attrs, bt_bdaddr_t *bd_addr);
 
 /** Callback for getting the player application settings values' text
 **  num_attr: specifies the number of value ids contained in p_vals
 */
-typedef void (* btrc_get_player_app_values_text_callback) (uint8_t attr_id, uint8_t num_val, uint8_t *p_vals);
+typedef void (* btrc_get_player_app_values_text_callback) (uint8_t attr_id, uint8_t num_val,
+    uint8_t *p_vals, bt_bdaddr_t *bd_addr);
 
 /** Callback for setting the player application settings values */
-typedef void (* btrc_set_player_app_value_callback) (btrc_player_settings_t *p_vals);
+typedef void (* btrc_set_player_app_value_callback) (btrc_player_settings_t *p_vals,
+    bt_bdaddr_t *bd_addr);
 
 /** Callback to fetch the get element attributes of the current song
 **  num_attr: specifies the number of attributes requested in p_attrs
 */
-typedef void (* btrc_get_element_attr_callback) (uint8_t num_attr, btrc_media_attr_t *p_attrs);
+typedef void (* btrc_get_element_attr_callback) (uint8_t num_attr, btrc_media_attr_t *p_attrs,
+    bt_bdaddr_t *bd_addr);
 
 /** Callback for register notification (Play state change/track change/...)
 **  param: Is only valid if event_id is BTRC_EVT_PLAY_POS_CHANGED
 */
-typedef void (* btrc_register_notification_callback) (btrc_event_id_t event_id, uint32_t param);
+typedef void (* btrc_register_notification_callback) (btrc_event_id_t event_id, uint32_t param,
+    bt_bdaddr_t *bd_addr);
 
 /* AVRCP 1.4 Enhancements */
 /** Callback for volume change on CT
 **  volume: Current volume setting on the CT (0-127)
 */
-typedef void (* btrc_volume_change_callback) (uint8_t volume, uint8_t ctype);
+typedef void (* btrc_volume_change_callback) (uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr);
 
 /** Callback for passthrough commands */
-typedef void (* btrc_passthrough_cmd_callback) (int id, int key_state);
+typedef void (* btrc_passthrough_cmd_callback) (int id, int key_state, bt_bdaddr_t *bd_addr);
+
+/** Callback for set addressed player response on TG **/
+typedef void (* btrc_set_addressed_player_callback) (uint16_t player_id, bt_bdaddr_t *bd_addr);
+
+/** Callback for set browsed player response on TG **/
+typedef void (* btrc_set_browsed_player_callback) (uint16_t player_id, bt_bdaddr_t *bd_addr);
+
+/** Callback for get folder items on TG
+**  num_attr: specifies the number of attributes requested in p_attr_ids
+*/
+typedef void (* btrc_get_folder_items_callback) (uint8_t scope, uint32_t start_item,
+              uint32_t end_item, uint8_t num_attr, uint32_t *p_attr_ids, bt_bdaddr_t *bd_addr);
+
+/** Callback for changing browsed path on TG **/
+typedef void (* btrc_change_path_callback) (uint8_t direction,
+                uint8_t* folder_uid, bt_bdaddr_t *bd_addr);
+
+/** Callback to fetch the get item attributes of the media item
+**  num_attr: specifies the number of attributes requested in p_attrs
+*/
+typedef void (* btrc_get_item_attr_callback) (uint8_t scope, uint8_t* uid, uint16_t uid_counter,
+                uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr);
+
+/** Callback for play request for the media item indicated by an identifier */
+typedef void (* btrc_play_item_callback) (uint8_t scope,
+                uint16_t uid_counter, uint8_t* uid, bt_bdaddr_t *bd_addr);
+
+/** Callback to fetch total number of items from a folder **/
+typedef void (* btrc_get_total_num_of_items_callback) (uint8_t scope, bt_bdaddr_t *bd_addr);
+
+/** Callback for conducting recursive search on a current browsed path for a specified string */
+typedef void (* btrc_search_callback) (uint16_t charset_id,
+                uint16_t str_len, uint8_t* p_str, bt_bdaddr_t *bd_addr);
+
+/** Callback to add a specified media item indicated by an identifier to now playing queue. */
+typedef void (* btrc_add_to_now_playing_callback) (uint8_t scope,
+                uint8_t* uid, uint16_t  uid_counter, bt_bdaddr_t *bd_addr);
 
 /** BT-RC Target callback structure. */
 typedef struct {
@@ -217,6 +396,15 @@
     btrc_register_notification_callback         register_notification_cb;
     btrc_volume_change_callback                 volume_change_cb;
     btrc_passthrough_cmd_callback               passthrough_cmd_cb;
+    btrc_set_addressed_player_callback          set_addressed_player_cb;
+    btrc_set_browsed_player_callback            set_browsed_player_cb;
+    btrc_get_folder_items_callback              get_folder_items_cb;
+    btrc_change_path_callback                   change_path_cb;
+    btrc_get_item_attr_callback                 get_item_attr_cb;
+    btrc_play_item_callback                     play_item_cb;
+    btrc_get_total_num_of_items_callback        get_total_num_of_items_cb;
+    btrc_search_callback                        search_cb;
+    btrc_add_to_now_playing_callback            add_to_now_playing_cb;
 } btrc_callbacks_t;
 
 /** Represents the standard BT-RC AVRCP Target interface. */
@@ -234,40 +422,45 @@
     **  2. Song duration/length
     **  3. Song position
     */
-    bt_status_t (*get_play_status_rsp)( btrc_play_status_t play_status, uint32_t song_len, uint32_t song_pos);
+    bt_status_t (*get_play_status_rsp)( bt_bdaddr_t *bd_addr, btrc_play_status_t play_status,
+        uint32_t song_len, uint32_t song_pos);
 
     /** Lists the support player application attributes (Shuffle/Repeat/...)
     **  num_attr: Specifies the number of attributes contained in the pointer p_attrs
     */
-    bt_status_t (*list_player_app_attr_rsp)( int num_attr, btrc_player_attr_t *p_attrs);
+    bt_status_t (*list_player_app_attr_rsp)( bt_bdaddr_t *bd_addr, int num_attr,
+        btrc_player_attr_t *p_attrs);
 
     /** Lists the support player application attributes (Shuffle Off/On/Group)
     **  num_val: Specifies the number of values contained in the pointer p_vals
     */
-    bt_status_t (*list_player_app_value_rsp)( int num_val, uint8_t *p_vals);
+    bt_status_t (*list_player_app_value_rsp)( bt_bdaddr_t *bd_addr, int num_val, uint8_t *p_vals);
 
     /** Returns the current application attribute values for each of the specified attr_id */
-    bt_status_t (*get_player_app_value_rsp)( btrc_player_settings_t *p_vals);
+    bt_status_t (*get_player_app_value_rsp)( bt_bdaddr_t *bd_addr, btrc_player_settings_t *p_vals);
 
     /** Returns the application attributes text ("Shuffle"/"Repeat"/...)
     **  num_attr: Specifies the number of attributes' text contained in the pointer p_attrs
     */
-    bt_status_t (*get_player_app_attr_text_rsp)( int num_attr, btrc_player_setting_text_t *p_attrs);
+    bt_status_t (*get_player_app_attr_text_rsp)( bt_bdaddr_t *bd_addr, int num_attr,
+        btrc_player_setting_text_t *p_attrs);
 
     /** Returns the application attributes text ("Shuffle"/"Repeat"/...)
     **  num_attr: Specifies the number of attribute values' text contained in the pointer p_vals
     */
-    bt_status_t (*get_player_app_value_text_rsp)( int num_val, btrc_player_setting_text_t *p_vals);
+    bt_status_t (*get_player_app_value_text_rsp)( bt_bdaddr_t *bd_addr, int num_val,
+        btrc_player_setting_text_t *p_vals);
 
     /** Returns the current songs' element attributes text ("Title"/"Album"/"Artist")
     **  num_attr: Specifies the number of attributes' text contained in the pointer p_attrs
     */
-    bt_status_t (*get_element_attr_rsp)( uint8_t num_attr, btrc_element_attr_val_t *p_attrs);
+    bt_status_t (*get_element_attr_rsp)( bt_bdaddr_t *bd_addr, uint8_t num_attr,
+        btrc_element_attr_val_t *p_attrs);
 
     /** Response to set player attribute request ("Shuffle"/"Repeat")
     **  rsp_status: Status of setting the player attributes for the current media player
     */
-    bt_status_t (*set_player_app_value_rsp)(btrc_status_t rsp_status);
+    bt_status_t (*set_player_app_value_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status);
 
     /* Response to the register notification request (Play state change/track change/...).
     ** event_id: Refers to the event_id this notification change corresponds too
@@ -287,16 +480,52 @@
     */
     bt_status_t (*set_volume)(uint8_t volume);
 
+    /* Set addressed player response from TG to CT */
+    bt_status_t (*set_addressed_player_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status);
+
+    /* Set browsed player response from TG to CT */
+    bt_status_t (*set_browsed_player_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
+        uint32_t num_items, uint16_t charset_id, uint8_t folder_depth,
+        btrc_br_folder_name_t *p_folders);
+
+    /* Get folder item list response from TG to CT */
+     bt_status_t (*get_folder_items_list_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
+        uint16_t uid_counter, uint8_t num_items, btrc_folder_items_t *p_items);
+
+    /* Change path response from TG to CT */
+    bt_status_t (*change_path_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
+        uint32_t num_items);
+
+    /** Returns the element's attributes num_attr: Specifies the number of attributes' text
+     * contained in the pointer p_attrs
+     */
+    bt_status_t (*get_item_attr_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
+        uint8_t num_attr, btrc_element_attr_val_t *p_attrs);
+
+    /* play media item response from TG to CT */
+    bt_status_t (*play_item_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status);
+
+    /* get total number of items response from TG to CT*/
+    bt_status_t (*get_total_num_of_items_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
+        uint32_t uid_counter, uint32_t num_items);
+
+    /* Search VFS response from TG to CT */
+    bt_status_t (*search_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status, uint32_t uid_counter,
+        uint32_t num_items);
+
+    /* add_to_now playing list response from TG to CT */
+    bt_status_t (*add_to_now_playing_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status);
+
     /** Closes the interface. */
     void  (*cleanup)( void );
 } btrc_interface_t;
 
-
-typedef void (* btrc_passthrough_rsp_callback) (int id, int key_state);
+typedef void (* btrc_passthrough_rsp_callback) (bt_bdaddr_t *bd_addr, int id, int key_state);
 
 typedef void (* btrc_groupnavigation_rsp_callback) (int id, int key_state);
 
-typedef void (* btrc_connection_state_callback) (bool state, bt_bdaddr_t *bd_addr);
+typedef void (* btrc_connection_state_callback) (
+    bool rc_connect, bool bt_connect, bt_bdaddr_t *bd_addr);
 
 typedef void (* btrc_ctrl_getrcfeatures_callback) (bt_bdaddr_t *bd_addr, int features);
 
@@ -325,6 +554,16 @@
 typedef void (* btrc_ctrl_play_status_changed_callback)(bt_bdaddr_t *bd_addr,
                                                             btrc_play_status_t play_status);
 
+typedef void (* btrc_ctrl_get_folder_items_callback )(bt_bdaddr_t *bd_addr,
+                                                            btrc_status_t status,
+                                                            const btrc_folder_items_t *folder_items,
+                                                            uint8_t count);
+
+typedef void (* btrc_ctrl_change_path_callback)(bt_bdaddr_t *bd_addr, uint8_t count);
+
+typedef void (* btrc_ctrl_set_browsed_player_callback )(
+    bt_bdaddr_t *bd_addr, uint8_t num_items, uint8_t depth);
+typedef void (* btrc_ctrl_set_addressed_player_callback)(bt_bdaddr_t *bd_addr, uint8_t status);
 /** BT-RC Controller callback structure. */
 typedef struct {
     /** set to sizeof(BtRcCallbacks) */
@@ -341,6 +580,10 @@
     btrc_ctrl_track_changed_callback                            track_changed_cb;
     btrc_ctrl_play_position_changed_callback                    play_position_changed_cb;
     btrc_ctrl_play_status_changed_callback                      play_status_changed_cb;
+    btrc_ctrl_get_folder_items_callback                         get_folder_items_cb;
+    btrc_ctrl_change_path_callback                              change_folder_path_cb;
+    btrc_ctrl_set_browsed_player_callback                       set_browsed_player_cb;
+    btrc_ctrl_set_addressed_player_callback                     set_addressed_player_cb;
 } btrc_ctrl_callbacks_t;
 
 /** Represents the standard BT-RC AVRCP Controller interface. */
@@ -365,6 +608,31 @@
     bt_status_t (*set_player_app_setting_cmd) (bt_bdaddr_t *bd_addr, uint8_t num_attrib,
             uint8_t* attrib_ids, uint8_t* attrib_vals);
 
+    /** send command to play a particular item */
+    bt_status_t (*play_item_cmd) (
+        bt_bdaddr_t *bd_addr, uint8_t scope, uint8_t *uid, uint16_t uid_counter);
+
+    /** get the playback state */
+    bt_status_t (*get_playback_state_cmd) (bt_bdaddr_t *bd_addr);
+
+    /** get the now playing list */
+    bt_status_t (*get_now_playing_list_cmd) (bt_bdaddr_t *bd_addr, uint8_t start, uint8_t items);
+
+    /** get the folder list */
+    bt_status_t (*get_folder_list_cmd) (bt_bdaddr_t *bd_addr, uint8_t start, uint8_t items);
+
+    /** get the folder list */
+    bt_status_t (*get_player_list_cmd) (bt_bdaddr_t *bd_addr, uint8_t start, uint8_t items);
+
+    /** get the folder list */
+    bt_status_t (*change_folder_path_cmd) (bt_bdaddr_t *bd_addr, uint8_t direction, uint8_t * uid);
+
+    /** set browsed player */
+    bt_status_t (*set_browsed_player_cmd) (bt_bdaddr_t *bd_addr, uint16_t player_id);
+
+    /** set addressed player */
+    bt_status_t (*set_addressed_player_cmd) (bt_bdaddr_t *bd_addr, uint16_t player_id);
+
     /** send rsp to set_abs_vol received from target */
     bt_status_t (*set_volume_rsp) (bt_bdaddr_t *bd_addr, uint8_t abs_vol, uint8_t label);
 
diff --git a/include/hardware/camera2.h b/include/hardware/camera2.h
index 2b7add0..547a1d7 100644
--- a/include/hardware/camera2.h
+++ b/include/hardware/camera2.h
@@ -146,7 +146,7 @@
 typedef struct camera2_jpeg_blob {
     uint16_t jpeg_blob_id;
     uint32_t jpeg_size;
-};
+} camera2_jpeg_blob_t;
 
 enum {
     CAMERA2_JPEG_BLOB_ID = 0x00FF
diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h
index a7df0ee..cec2ab3 100644
--- a/include/hardware/camera3.h
+++ b/include/hardware/camera3.h
@@ -1479,6 +1479,13 @@
      *      android.lens.opticalStabilizationMode (if it is supported)
      *      android.scaler.cropRegion
      *      android.statistics.faceDetectMode (if it is supported)
+     *   6. To reduce the amount of data passed across process boundaries at
+     *      high frame rate, within one batch, camera framework only propagates
+     *      the last shutter notify and the last capture results (including partial
+     *      results and final result) to the app. The shutter notifies and capture
+     *      results for the other requests in the batch are derived by
+     *      the camera framework. As a result, the HAL can return empty metadata
+     *      except for the last result in the batch.
      *
      * For more details about high speed stream requirements, see
      * android.control.availableHighSpeedVideoConfigurations and CONSTRAINED_HIGH_SPEED_VIDEO
@@ -1597,6 +1604,13 @@
      *   value of this is 0.
      *   For all streams passed via configure_streams(), the HAL must write
      *   over this field with its usage flags.
+     *
+     *   From Android O, the usage flag for an output stream may be bitwise
+     *   combination of usage flags for multiple consumers, for the purpose of
+     *   sharing one camera stream between those consumers. The HAL must fail
+     *   configure_streams call with -EINVAL if the combined flags cannot be
+     *   supported due to imcompatible buffer format, dataSpace, or other hardware
+     *   limitations.
      */
     uint32_t usage;
 
diff --git a/include/hardware/camera_common.h b/include/hardware/camera_common.h
index c74d7bb..7bafa88 100644
--- a/include/hardware/camera_common.h
+++ b/include/hardware/camera_common.h
@@ -143,8 +143,8 @@
 #define CAMERA_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) // DEPRECATED
 #define CAMERA_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0) // NO LONGER SUPPORTED
 #define CAMERA_DEVICE_API_VERSION_2_1 HARDWARE_DEVICE_API_VERSION(2, 1) // NO LONGER SUPPORTED
-#define CAMERA_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0)
-#define CAMERA_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1)
+#define CAMERA_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0) // NO LONGER SUPPORTED
+#define CAMERA_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1) // NO LONGER SUPPORTED
 #define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2)
 #define CAMERA_DEVICE_API_VERSION_3_3 HARDWARE_DEVICE_API_VERSION(3, 3)
 #define CAMERA_DEVICE_API_VERSION_3_4 HARDWARE_DEVICE_API_VERSION(3, 4)
diff --git a/include/hardware/context_hub.h b/include/hardware/context_hub.h
index 828f2dd..aaa4274 100644
--- a/include/hardware/context_hub.h
+++ b/include/hardware/context_hub.h
@@ -78,17 +78,17 @@
 #define NANOAPP_VENDOR_ALL_APPS       0x0000000000FFFFFFULL
 
 #define NANOAPP_VENDOR(name) \
-    (((uint64_t)name[0] << 56) | \
-    ((uint64_t)name[1] << 48) | \
-    ((uint64_t)name[2] << 40) | \
-    ((uint64_t)name[3] << 32) | \
-    ((uint64_t)name[4] << 24))
+    (((uint64_t)(name)[0] << 56) | \
+    ((uint64_t)(name)[1] << 48) | \
+    ((uint64_t)(name)[2] << 40) | \
+    ((uint64_t)(name)[3] << 32) | \
+    ((uint64_t)(name)[4] << 24))
 
 /*
  * generates the NANOAPP ID from vendor id and app seq# id
  */
 #define NANO_APP_ID(vendor, seq_id) \
-	(((uint64_t)vendor & NANOAPP_VENDORS_ALL) | ((uint64_t)seq_id & NANOAPP_VENDOR_ALL_APPS))
+	(((uint64_t)(vendor) & NANOAPP_VENDORS_ALL) | ((uint64_t)(seq_id) & NANOAPP_VENDOR_ALL_APPS))
 
 struct hub_app_name_t {
     uint64_t id;
diff --git a/include/hardware/fb.h b/include/hardware/fb.h
index 9df9416..65720a3 100644
--- a/include/hardware/fb.h
+++ b/include/hardware/fb.h
@@ -160,7 +160,7 @@
 static inline int framebuffer_open(const struct hw_module_t* module,
         struct framebuffer_device_t** device) {
     return module->methods->open(module,
-            GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);
+            GRALLOC_HARDWARE_FB0, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int framebuffer_close(struct framebuffer_device_t* device) {
diff --git a/include/hardware/fingerprint.h b/include/hardware/fingerprint.h
index 618ca7e..6e08d6c 100644
--- a/include/hardware/fingerprint.h
+++ b/include/hardware/fingerprint.h
@@ -18,10 +18,12 @@
 #define ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H
 
 #include <hardware/hw_auth_token.h>
+#include <hardware/hardware.h>
 
 #define FINGERPRINT_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
 #define FINGERPRINT_MODULE_API_VERSION_2_0 HARDWARE_MODULE_API_VERSION(2, 0)
 #define FINGERPRINT_MODULE_API_VERSION_2_1 HARDWARE_MODULE_API_VERSION(2, 1)
+#define FINGERPRINT_MODULE_API_VERSION_3_0 HARDWARE_MODULE_API_VERSION(3, 0)
 #define FINGERPRINT_HARDWARE_MODULE_ID "fingerprint"
 
 typedef enum fingerprint_msg_type {
@@ -50,6 +52,7 @@
     FINGERPRINT_ERROR_NO_SPACE = 4, /* No space available to store a template */
     FINGERPRINT_ERROR_CANCELED = 5, /* The current operation can't proceed. See above. */
     FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6, /* fingerprint with given id can't be removed */
+    FINGERPRINT_ERROR_LOCKOUT = 7, /* the fingerprint hardware is in lockout due to too many attempts */
     FINGERPRINT_ERROR_VENDOR_BASE = 1000 /* vendor-specific error messages start here */
 } fingerprint_error_t;
 
@@ -68,6 +71,8 @@
     FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3, /* sensor needs to be cleaned */
     FINGERPRINT_ACQUIRED_TOO_SLOW = 4, /* mostly swipe-type sensors; not enough data collected */
     FINGERPRINT_ACQUIRED_TOO_FAST = 5, /* for swipe and area sensors; tell user to slow down*/
+    FINGERPRINT_ACQUIRED_DETECTED = 6, /* when the finger is first detected. Used to optimize wakeup.
+                                          Should be followed by one of the above messages */
     FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000 /* vendor-specific acquisition messages start here */
 } fingerprint_acquired_info_t;
 
@@ -84,14 +89,13 @@
     uint64_t msg; /* Vendor specific message. Used for user guidance */
 } fingerprint_enroll_t;
 
-typedef struct fingerprint_enumerated {
+typedef struct fingerprint_iterator {
     fingerprint_finger_id_t finger;
     uint32_t remaining_templates;
-} fingerprint_enumerated_t;
+} fingerprint_iterator_t;
 
-typedef struct fingerprint_removed {
-    fingerprint_finger_id_t finger;
-} fingerprint_removed_t;
+typedef fingerprint_iterator_t fingerprint_enumerated_t;
+typedef fingerprint_iterator_t fingerprint_removed_t;
 
 typedef struct fingerprint_acquired {
     fingerprint_acquired_info_t acquired_info; /* information about the image */
@@ -206,12 +210,13 @@
     /*
      * Enumerate all the fingerprint templates found in the directory set by
      * set_active_group()
-     * For each template found notify() will be called with:
+     * For each template found a notify() will be called with:
      * fingerprint_msg.type == FINGERPRINT_TEMPLATE_ENUMERATED
      * fingerprint_msg.data.enumerated.finger indicating a template id
      * fingerprint_msg.data.enumerated.remaining_templates indicating how many more
      * enumeration messages to expect.
-     *
+     * Note: If there are no fingerprints, then this should return 0 and the first fingerprint
+     *                  enumerated should have fingerid=0 and remaining=0
      * Function return: 0 if enumerate request is accepted
      *                  or a negative number in case of error, generally from the errno.h set.
      */
@@ -221,9 +226,14 @@
      * Fingerprint remove request:
      * Deletes a fingerprint template.
      * Works only within the path set by set_active_group().
-     * notify() will be called with details on the template deleted.
-     * fingerprint_msg.type == FINGERPRINT_TEMPLATE_REMOVED and
-     * fingerprint_msg.data.removed.finger indicating the template id removed.
+     * The fid parameter can be used as a widcard:
+     *   * fid == 0 -- delete all the templates in the group.
+     *   * fid != 0 -- delete this specific template from the group.
+     * For each template found a notify() will be called with:
+     * fingerprint_msg.type == FINGERPRINT_TEMPLATE_REMOVED
+     * fingerprint_msg.data.removed.finger indicating a template id deleted
+     * fingerprint_msg.data.removed.remaining_templates indicating how many more
+     * templates will be deleted by this operation.
      *
      * Function return: 0 if fingerprint template(s) can be successfully deleted
      *                  or a negative number in case of error, generally from the errno.h set.
diff --git a/include/hardware/fused_location.h b/include/hardware/fused_location.h
index 73360a1..550e193 100644
--- a/include/hardware/fused_location.h
+++ b/include/hardware/fused_location.h
@@ -19,6 +19,7 @@
 
 #include <hardware/hardware.h>
 
+#include "gnss-base.h"
 
 /**
  * This header file defines the interface of the Fused Location Provider.
@@ -103,16 +104,6 @@
 #define FLP_STATUS_LOCATION_UNAVAILABLE       1
 
 /**
- * This constant is used with the batched locations
- * APIs. Batching is mandatory when FLP implementation
- * is supported. If the flag is set, the hardware implementation
- * will wake up the application processor when the FIFO is full,
- * If the flag is not set, the hardware implementation will drop
- * the oldest data when the FIFO is full.
- */
-#define FLP_BATCH_WAKEUP_ON_FIFO_FULL        0x0000001
-
-/**
  * While batching, the implementation should not call the
  * flp_location_callback on every location fix. However,
  * sometimes in high power mode, the system might need
diff --git a/include/hardware/gnss-base.h b/include/hardware/gnss-base.h
new file mode 100644
index 0000000..e56020d
--- /dev/null
+++ b/include/hardware/gnss-base.h
@@ -0,0 +1,275 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+// Source: android.hardware.gnss@1.0
+// Root: android.hardware:hardware/interfaces
+
+#ifndef HIDL_GENERATED_ANDROID_HARDWARE_GNSS_V1_0_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_ANDROID_HARDWARE_GNSS_V1_0_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+    GNSS_MAX_SVS_COUNT = 64u, // 64
+};
+
+enum {
+    GNSS_CONSTELLATION_UNKNOWN = 0,
+    GNSS_CONSTELLATION_GPS = 1,
+    GNSS_CONSTELLATION_SBAS = 2,
+    GNSS_CONSTELLATION_GLONASS = 3,
+    GNSS_CONSTELLATION_QZSS = 4,
+    GNSS_CONSTELLATION_BEIDOU = 5,
+    GNSS_CONSTELLATION_GALILEO = 6,
+};
+
+enum {
+    GPS_LOCATION_HAS_LAT_LONG = 1, // 0x0001
+    GPS_LOCATION_HAS_ALTITUDE = 2, // 0x0002
+    GPS_LOCATION_HAS_SPEED = 4, // 0x0004
+    GPS_LOCATION_HAS_BEARING = 8, // 0x0008
+    GPS_LOCATION_HAS_HORIZONTAL_ACCURACY = 16, // 0x0010
+    GPS_LOCATION_HAS_VERTICAL_ACCURACY = 32, // 0x0020
+    GPS_LOCATION_HAS_SPEED_ACCURACY = 64, // 0x0040
+    GPS_LOCATION_HAS_BEARING_ACCURACY = 128, // 0x0080
+};
+
+enum {
+    APN_IP_INVALID = 0,
+    APN_IP_IPV4 = 1,
+    APN_IP_IPV6 = 2,
+    APN_IP_IPV4V6 = 3,
+};
+
+enum {
+    AGPS_TYPE_SUPL = 1,
+    AGPS_TYPE_C2K = 2,
+};
+
+enum {
+    GNSS_REQUEST_AGNSS_DATA_CONN = 1,
+    GNSS_RELEASE_AGNSS_DATA_CONN = 2,
+    GNSS_AGNSS_DATA_CONNECTED = 3,
+    GNSS_AGNSS_DATA_CONN_DONE = 4,
+    GNSS_AGNSS_DATA_CONN_FAILED = 5,
+};
+
+enum {
+    AGPS_SETID_TYPE_NONE = 0,
+    AGPS_SETID_TYPE_IMSI = 1,
+    AGPS_SETID_TYPE_MSISDM = 2,
+};
+
+enum {
+    AGPS_RIL_NETWORK_TYPE_MOBILE = 0,
+    AGPS_RIL_NETWORK_TYPE_WIFI = 1,
+    AGPS_RIL_NETWORK_TYPE_MMS = 2,
+    AGPS_RIL_NETWORK_TYPE_SUPL = 3,
+    AGPS_RIL_NETWORK_TYPE_DUN = 4,
+    AGPS_RIL_NETWORK_TYPE_HIPRI = 5,
+    AGPS_RIL_NETWORK_TYPE_WIMAX = 6,
+};
+
+enum {
+    AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1,
+    AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2,
+    AGPS_REF_LOCATION_TYPE_LTE_CELLID = 4,
+};
+
+enum {
+    AGPS_RIL_REQUEST_SETID_IMSI = 1u, // (1 << 0L)
+    AGPS_RIL_REQUEST_SETID_MSISDN = 2u, // (1 << 1L)
+};
+
+enum {
+    GPS_POSITION_MODE_STANDALONE = 0,
+    GPS_POSITION_MODE_MS_BASED = 1,
+    GPS_POSITION_MODE_MS_ASSISTED = 2,
+};
+
+enum {
+    GPS_POSITION_RECURRENCE_PERIODIC = 0u, // 0
+    GPS_POSITION_RECURRENCE_SINGLE = 1u, // 1
+};
+
+enum {
+    GPS_DELETE_EPHEMERIS = 1, // 0x0001
+    GPS_DELETE_ALMANAC = 2, // 0x0002
+    GPS_DELETE_POSITION = 4, // 0x0004
+    GPS_DELETE_TIME = 8, // 0x0008
+    GPS_DELETE_IONO = 16, // 0x0010
+    GPS_DELETE_UTC = 32, // 0x0020
+    GPS_DELETE_HEALTH = 64, // 0x0040
+    GPS_DELETE_SVDIR = 128, // 0x0080
+    GPS_DELETE_SVSTEER = 256, // 0x0100
+    GPS_DELETE_SADATA = 512, // 0x0200
+    GPS_DELETE_RTI = 1024, // 0x0400
+    GPS_DELETE_CELLDB_INFO = 32768, // 0x8000
+    GPS_DELETE_ALL = 65535, // 0xFFFF
+};
+
+enum {
+    FLP_BATCH_WAKEUP_ON_FIFO_FULL = 1, // 0x01
+};
+
+enum {
+    GPS_CAPABILITY_SCHEDULING = 1u, // (1 << 0)
+    GPS_CAPABILITY_MSB = 2u, // (1 << 1)
+    GPS_CAPABILITY_MSA = 4u, // (1 << 2)
+    GPS_CAPABILITY_SINGLE_SHOT = 8u, // (1 << 3)
+    GPS_CAPABILITY_ON_DEMAND_TIME = 16u, // (1 << 4)
+    GPS_CAPABILITY_GEOFENCING = 32u, // (1 << 5)
+    GPS_CAPABILITY_MEASUREMENTS = 64u, // (1 << 6)
+    GPS_CAPABILITY_NAV_MESSAGES = 128u, // (1 << 7)
+};
+
+enum {
+    GPS_STATUS_NONE = 0,
+    GPS_STATUS_SESSION_BEGIN = 1,
+    GPS_STATUS_SESSION_END = 2,
+    GPS_STATUS_ENGINE_ON = 3,
+    GPS_STATUS_ENGINE_OFF = 4,
+};
+
+enum {
+    GNSS_SV_FLAGS_NONE = 0,
+    GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA = 1, // (1 << 0)
+    GNSS_SV_FLAGS_HAS_ALMANAC_DATA = 2, // (1 << 1)
+    GNSS_SV_FLAGS_USED_IN_FIX = 4, // (1 << 2)
+    GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY = 8, // (1 << 3)
+};
+
+enum {
+    GPS_GEOFENCE_ENTERED = 1, // (1 << 0L)
+    GPS_GEOFENCE_EXITED = 2, // (1 << 1L)
+    GPS_GEOFENCE_UNCERTAIN = 4, // (1 << 2L)
+};
+
+enum {
+    GPS_GEOFENCE_UNAVAILABLE = 1, // (1 << 0L)
+    GPS_GEOFENCE_AVAILABLE = 2, // (1 << 1L)
+};
+
+enum {
+    GPS_GEOFENCE_OPERATION_SUCCESS = 0,
+    GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = -100, // (-100)
+    GPS_GEOFENCE_ERROR_ID_EXISTS = -101, // (-101)
+    GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102, // (-102)
+    GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103, // (-103)
+    GPS_GEOFENCE_ERROR_GENERIC = -149, // (-149)
+};
+
+enum {
+    GPS_MEASUREMENT_SUCCESS = 0,
+    GPS_MEASUREMENT_ERROR_ALREADY_INIT = -100, // (-100)
+    GPS_MEASUREMENT_ERROR_GENERIC = -101, // (-101)
+};
+
+enum {
+    GNSS_CLOCK_HAS_LEAP_SECOND = 1, // (1 << 0)
+    GNSS_CLOCK_HAS_TIME_UNCERTAINTY = 2, // (1 << 1)
+    GNSS_CLOCK_HAS_FULL_BIAS = 4, // (1 << 2)
+    GNSS_CLOCK_HAS_BIAS = 8, // (1 << 3)
+    GNSS_CLOCK_HAS_BIAS_UNCERTAINTY = 16, // (1 << 4)
+    GNSS_CLOCK_HAS_DRIFT = 32, // (1 << 5)
+    GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY = 64, // (1 << 6)
+};
+
+enum {
+    GNSS_MEASUREMENT_HAS_SNR = 1u, // (1 << 0)
+    GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY = 512u, // (1 << 9)
+    GNSS_MEASUREMENT_HAS_CARRIER_CYCLES = 1024u, // (1 << 10)
+    GNSS_MEASUREMENT_HAS_CARRIER_PHASE = 2048u, // (1 << 11)
+    GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY = 4096u, // (1 << 12)
+    GNSS_MEASUREMENT_HAS_AUTOMATIC_GAIN_CONTROL = 8192u, // (1 << 13)
+};
+
+enum {
+    GNSS_MULTIPATH_INDICATOR_UNKNOWN = 0,
+    GNSS_MULTIPATH_INDICATOR_PRESENT = 1,
+    GNSS_MULTIPATH_INDICATIOR_NOT_PRESENT = 2,
+};
+
+enum {
+    GNSS_MEASUREMENT_STATE_UNKNOWN = 0u, // 0
+    GNSS_MEASUREMENT_STATE_CODE_LOCK = 1u, // (1 << 0)
+    GNSS_MEASUREMENT_STATE_BIT_SYNC = 2u, // (1 << 1)
+    GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC = 4u, // (1 << 2)
+    GNSS_MEASUREMENT_STATE_TOW_DECODED = 8u, // (1 << 3)
+    GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS = 16u, // (1 << 4)
+    GNSS_MEASUREMENT_STATE_SYMBOL_SYNC = 32u, // (1 << 5)
+    GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC = 64u, // (1 << 6)
+    GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED = 128u, // (1 << 7)
+    GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC = 256u, // (1 << 8)
+    GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC = 512u, // (1 << 9)
+    GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK = 1024u, // (1 << 10)
+    GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK = 2048u, // (1 << 11)
+    GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC = 4096u, // (1 << 12)
+    GNSS_MEASUREMENT_STATE_SBAS_SYNC = 8192u, // (1 << 13)
+    GNSS_MEASUREMENT_STATE_TOW_KNOWN = 16384u, // (1 << 14)
+    GNSS_MEASUREMENT_STATE_GLO_TOD_KNOWN = 32768u, // (1 << 15)
+};
+
+enum {
+    GNSS_ADR_STATE_UNKNOWN = 0,
+    GNSS_ADR_STATE_VALID = 1, // (1 << 0)
+    GNSS_ADR_STATE_RESET = 2, // (1 << 1)
+    GNSS_ADR_STATE_CYCLE_SLIP = 4, // (1 << 2)
+};
+
+enum {
+    GPS_NAVIGATION_MESSAGE_SUCCESS = 0,
+    GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT = -100, // (-100)
+    GPS_NAVIGATION_MESSAGE_ERROR_GENERIC = -101, // (-101)
+};
+
+enum {
+    GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN = 0,
+    GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_L1CA = 257, // 0x0101
+    GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_L2CNAV = 258, // 0x0102
+    GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_L5CNAV = 259, // 0x0103
+    GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_CNAV2 = 260, // 0x0104
+    GNSS_NAVIGATION_MESSAGE_TYPE_GLO_L1CA = 769, // 0x0301
+    GNSS_NAVIGATION_MESSAGE_TYPE_BDS_D1 = 1281, // 0x0501
+    GNSS_NAVIGATION_MESSAGE_TYPE_BDS_D2 = 1282, // 0x0502
+    GNSS_NAVIGATION_MESSAGE_TYPE_GAL_I = 1537, // 0x0601
+    GNSS_NAVIGATION_MESSAGE_TYPE_GAL_F = 1538, // 0x0602
+};
+
+typedef enum {
+    NAV_MESSAGE_STATUS_PARITY_PASSED = 1, // (1 << 0)
+    NAV_MESSAGE_STATUS_PARITY_REBUILT = 2, // (1 << 1)
+    NAV_MESSAGE_STATUS_UNKNOWN = 0,
+} navigation_message_status;
+
+enum {
+    GPS_NI_TYPE_VOICE = 1,
+    GPS_NI_TYPE_UMTS_SUPL = 2,
+    GPS_NI_TYPE_UMTS_CTRL_PLANE = 3,
+};
+
+enum {
+    GPS_NI_NEED_NOTIFY = 1u, // 0x0001
+    GPS_NI_NEED_VERIFY = 2u, // 0x0002
+    GPS_NI_PRIVACY_OVERRIDE = 4u, // 0x0004
+};
+
+enum {
+    GPS_NI_RESPONSE_ACCEPT = 1,
+    GPS_NI_RESPONSE_DENY = 2,
+    GPS_NI_RESPONSE_NORESP = 3,
+};
+
+enum {
+    GPS_ENC_NONE = 0,
+    GPS_ENC_SUPL_GSM_DEFAULT = 1,
+    GPS_ENC_SUPL_UTF8 = 2,
+    GPS_ENC_SUPL_UCS2 = 3,
+    GPS_ENC_UNKNOWN = -1, // (-1)
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // HIDL_GENERATED_ANDROID_HARDWARE_GNSS_V1_0_EXPORTED_CONSTANTS_H_
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
index acf601b..4e108b3 100644
--- a/include/hardware/gps.h
+++ b/include/hardware/gps.h
@@ -26,8 +26,42 @@
 
 #include <hardware/hardware.h>
 
+#include "gnss-base.h"
+
 __BEGIN_DECLS
 
+/*
+ * Enums defined in HIDL in hardware/interfaces are auto-generated and present
+ * in gnss-base.h.
+ */
+
+/* for compatibility */
+
+/** Maximum number of SVs for gps_sv_status_callback(). */
+#define GNSS_MAX_SVS GNSS_MAX_SVS_COUNT
+/** Maximum number of Measurements in gnss_measurement_callback(). */
+#define GNSS_MAX_MEASUREMENT GNSS_MAX_SVS_COUNT
+
+#define GPS_REQUEST_AGPS_DATA_CONN GNSS_REQUEST_AGNSS_DATA_CONN
+#define GPS_RELEASE_AGPS_DATA_CONN GNSS_RELEASE_AGNSS_DATA_CONN
+#define GPS_AGPS_DATA_CONNECTED GNSS_AGNSS_DATA_CONNECTED
+#define GPS_AGPS_DATA_CONN_DONE GNSS_AGNSS_DATA_CONN_DONE
+#define GPS_AGPS_DATA_CONN_FAILED GNSS_AGNSS_DATA_CONN_FAILED
+#define AGPS_RIL_NETWORK_TYPE_MOBILE_MMS AGPS_RIL_NETWORK_TYPE_MMS
+#define AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL AGPS_RIL_NETWORK_TYPE_SUPL
+#define AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN AGPS_RIL_NETWORK_TYPE_DUN
+#define AGPS_RIL_NETWORK_TTYPE_MOBILE_HIPRI AGPS_RIL_NETWORK_TYPE_HIPRI
+#define AGPS_RIL_NETWORK_TTYPE_WIMAX AGPS_RIL_NETWORK_TYPE_WIMAX
+#define GNSS_MULTIPATH_INDICATOR_NOT_PRESENT GNSS_MULTIPATH_INDICATIOR_NOT_PRESENT
+#define AGPS_SETID_TYPE_MSISDN AGPS_SETID_TYPE_MSISDM
+#define GPS_MEASUREMENT_OPERATION_SUCCESS GPS_MEASUREMENT_SUCCESS
+#define GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS GPS_NAVIGATION_MESSAGE_SUCCESS
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L1CA GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_L1CA
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L2CNAV GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_L2CNAV
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L5CNAV GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_L5CNAV
+#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_CNAV2 GNSS_NAVIGATION_MESSAGE_TYPE_GNSS_CNAV2
+#define GPS_LOCATION_HAS_ACCURACY GPS_LOCATION_HAS_HORIZONTAL_ACCURACY
+
 /**
  * The id of this module
  */
@@ -39,127 +73,34 @@
 
 /** Maximum number of SVs for gps_sv_status_callback(). */
 #define GPS_MAX_SVS 32
-/** Maximum number of SVs for gps_sv_status_callback(). */
-#define GNSS_MAX_SVS 64
 
 /** Maximum number of Measurements in gps_measurement_callback(). */
 #define GPS_MAX_MEASUREMENT   32
 
-/** Maximum number of Measurements in gnss_measurement_callback(). */
-#define GNSS_MAX_MEASUREMENT   64
-
 /** Requested operational mode for GPS operation. */
 typedef uint32_t GpsPositionMode;
-/* IMPORTANT: Note that the following values must match
- * constants in GpsLocationProvider.java. */
-/** Mode for running GPS standalone (no assistance). */
-#define GPS_POSITION_MODE_STANDALONE    0
-/** AGPS MS-Based mode. */
-#define GPS_POSITION_MODE_MS_BASED      1
-/**
- * AGPS MS-Assisted mode. This mode is not maintained by the platform anymore.
- * It is strongly recommended to use GPS_POSITION_MODE_MS_BASED instead.
- */
-#define GPS_POSITION_MODE_MS_ASSISTED   2
 
 /** Requested recurrence mode for GPS operation. */
 typedef uint32_t GpsPositionRecurrence;
-/* IMPORTANT: Note that the following values must match
- * constants in GpsLocationProvider.java. */
-/** Receive GPS fixes on a recurring basis at a specified period. */
-#define GPS_POSITION_RECURRENCE_PERIODIC    0
-/** Request a single shot GPS fix. */
-#define GPS_POSITION_RECURRENCE_SINGLE      1
 
 /** GPS status event values. */
 typedef uint16_t GpsStatusValue;
-/* IMPORTANT: Note that the following values must match
- * constants in GpsLocationProvider.java. */
-/** GPS status unknown. */
-#define GPS_STATUS_NONE             0
-/** GPS has begun navigating. */
-#define GPS_STATUS_SESSION_BEGIN    1
-/** GPS has stopped navigating. */
-#define GPS_STATUS_SESSION_END      2
-/** GPS has powered on but is not navigating. */
-#define GPS_STATUS_ENGINE_ON        3
-/** GPS is powered off. */
-#define GPS_STATUS_ENGINE_OFF       4
 
 /** Flags to indicate which values are valid in a GpsLocation. */
 typedef uint16_t GpsLocationFlags;
-/* IMPORTANT: Note that the following values must match
- * constants in GpsLocationProvider.java. */
-/** GpsLocation has valid latitude and longitude. */
-#define GPS_LOCATION_HAS_LAT_LONG   0x0001
-/** GpsLocation has valid altitude. */
-#define GPS_LOCATION_HAS_ALTITUDE   0x0002
-/** GpsLocation has valid speed. */
-#define GPS_LOCATION_HAS_SPEED      0x0004
-/** GpsLocation has valid bearing. */
-#define GPS_LOCATION_HAS_BEARING    0x0008
-/** GpsLocation has valid accuracy. */
-#define GPS_LOCATION_HAS_ACCURACY   0x0010
-
-/** Flags for the gps_set_capabilities callback. */
-
-/**
- * GPS HAL schedules fixes for GPS_POSITION_RECURRENCE_PERIODIC mode. If this is
- * not set, then the framework will use 1000ms for min_interval and will start
- * and call start() and stop() to schedule the GPS.
- */
-#define GPS_CAPABILITY_SCHEDULING       (1 << 0)
-/** GPS supports MS-Based AGPS mode */
-#define GPS_CAPABILITY_MSB              (1 << 1)
-/** GPS supports MS-Assisted AGPS mode */
-#define GPS_CAPABILITY_MSA              (1 << 2)
-/** GPS supports single-shot fixes */
-#define GPS_CAPABILITY_SINGLE_SHOT      (1 << 3)
-/** GPS supports on demand time injection */
-#define GPS_CAPABILITY_ON_DEMAND_TIME   (1 << 4)
-/** GPS supports Geofencing  */
-#define GPS_CAPABILITY_GEOFENCING       (1 << 5)
-/** GPS supports Measurements. */
-#define GPS_CAPABILITY_MEASUREMENTS     (1 << 6)
-/** GPS supports Navigation Messages */
-#define GPS_CAPABILITY_NAV_MESSAGES     (1 << 7)
 
 /**
  * Flags used to specify which aiding data to delete when calling
  * delete_aiding_data().
  */
 typedef uint16_t GpsAidingData;
-/* IMPORTANT: Note that the following values must match
- * constants in GpsLocationProvider.java. */
-#define GPS_DELETE_EPHEMERIS        0x0001
-#define GPS_DELETE_ALMANAC          0x0002
-#define GPS_DELETE_POSITION         0x0004
-#define GPS_DELETE_TIME             0x0008
-#define GPS_DELETE_IONO             0x0010
-#define GPS_DELETE_UTC              0x0020
-#define GPS_DELETE_HEALTH           0x0040
-#define GPS_DELETE_SVDIR            0x0080
-#define GPS_DELETE_SVSTEER          0x0100
-#define GPS_DELETE_SADATA           0x0200
-#define GPS_DELETE_RTI              0x0400
-#define GPS_DELETE_CELLDB_INFO      0x8000
-#define GPS_DELETE_ALL              0xFFFF
 
 /** AGPS type */
 typedef uint16_t AGpsType;
-#define AGPS_TYPE_SUPL          1
-#define AGPS_TYPE_C2K           2
 
 typedef uint16_t AGpsSetIDType;
-#define AGPS_SETID_TYPE_NONE    0
-#define AGPS_SETID_TYPE_IMSI    1
-#define AGPS_SETID_TYPE_MSISDN  2
 
 typedef uint16_t ApnIpType;
-#define APN_IP_INVALID          0
-#define APN_IP_IPV4             1
-#define APN_IP_IPV6             2
-#define APN_IP_IPV4V6           3
 
 /**
  * String length constants
@@ -171,71 +112,31 @@
  * GpsNiType constants
  */
 typedef uint32_t GpsNiType;
-#define GPS_NI_TYPE_VOICE              1
-#define GPS_NI_TYPE_UMTS_SUPL          2
-#define GPS_NI_TYPE_UMTS_CTRL_PLANE    3
 
 /**
  * GpsNiNotifyFlags constants
  */
 typedef uint32_t GpsNiNotifyFlags;
-/** NI requires notification */
-#define GPS_NI_NEED_NOTIFY          0x0001
-/** NI requires verification */
-#define GPS_NI_NEED_VERIFY          0x0002
-/** NI requires privacy override, no notification/minimal trace */
-#define GPS_NI_PRIVACY_OVERRIDE     0x0004
 
 /**
  * GPS NI responses, used to define the response in
  * NI structures
  */
 typedef int GpsUserResponseType;
-#define GPS_NI_RESPONSE_ACCEPT         1
-#define GPS_NI_RESPONSE_DENY           2
-#define GPS_NI_RESPONSE_NORESP         3
 
 /**
  * NI data encoding scheme
  */
 typedef int GpsNiEncodingType;
-#define GPS_ENC_NONE                   0
-#define GPS_ENC_SUPL_GSM_DEFAULT       1
-#define GPS_ENC_SUPL_UTF8              2
-#define GPS_ENC_SUPL_UCS2              3
-#define GPS_ENC_UNKNOWN                -1
 
 /** AGPS status event values. */
 typedef uint16_t AGpsStatusValue;
-/** GPS requests data connection for AGPS. */
-#define GPS_REQUEST_AGPS_DATA_CONN  1
-/** GPS releases the AGPS data connection. */
-#define GPS_RELEASE_AGPS_DATA_CONN  2
-/** AGPS data connection initiated */
-#define GPS_AGPS_DATA_CONNECTED     3
-/** AGPS data connection completed */
-#define GPS_AGPS_DATA_CONN_DONE     4
-/** AGPS data connection failed */
-#define GPS_AGPS_DATA_CONN_FAILED   5
 
 typedef uint16_t AGpsRefLocationType;
-#define AGPS_REF_LOCATION_TYPE_GSM_CELLID   1
-#define AGPS_REF_LOCATION_TYPE_UMTS_CELLID  2
-#define AGPS_REF_LOCATION_TYPE_MAC          3
-#define AGPS_REF_LOCATION_TYPE_LTE_CELLID   4
 
 /* Deprecated, to be removed in the next Android release. */
 #define AGPS_REG_LOCATION_TYPE_MAC          3
 
-/** Network types for update_network_state "type" parameter */
-#define AGPS_RIL_NETWORK_TYPE_MOBILE        0
-#define AGPS_RIL_NETWORK_TYPE_WIFI          1
-#define AGPS_RIL_NETWORK_TYPE_MOBILE_MMS    2
-#define AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL   3
-#define AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN   4
-#define AGPS_RIL_NETWORK_TTYPE_MOBILE_HIPRI 5
-#define AGPS_RIL_NETWORK_TTYPE_WIMAX        6
-
 /* The following typedef together with its constants below are deprecated, and
  * will be removed in the next release. */
 typedef uint16_t GpsClockFlags;
@@ -251,20 +152,6 @@
  * Flags to indicate what fields in GnssClock are valid.
  */
 typedef uint16_t GnssClockFlags;
-/** A valid 'leap second' is stored in the data structure. */
-#define GNSS_CLOCK_HAS_LEAP_SECOND               (1<<0)
-/** A valid 'time uncertainty' is stored in the data structure. */
-#define GNSS_CLOCK_HAS_TIME_UNCERTAINTY          (1<<1)
-/** A valid 'full bias' is stored in the data structure. */
-#define GNSS_CLOCK_HAS_FULL_BIAS                 (1<<2)
-/** A valid 'bias' is stored in the data structure. */
-#define GNSS_CLOCK_HAS_BIAS                      (1<<3)
-/** A valid 'bias uncertainty' is stored in the data structure. */
-#define GNSS_CLOCK_HAS_BIAS_UNCERTAINTY          (1<<4)
-/** A valid 'drift' is stored in the data structure. */
-#define GNSS_CLOCK_HAS_DRIFT                     (1<<5)
-/** A valid 'drift uncertainty' is stored in the data structure. */
-#define GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY         (1<<6)
 
 /* The following typedef together with its constants below are deprecated, and
  * will be removed in the next release. */
@@ -300,16 +187,6 @@
  * Flags to indicate what fields in GnssMeasurement are valid.
  */
 typedef uint32_t GnssMeasurementFlags;
-/** A valid 'snr' is stored in the data structure. */
-#define GNSS_MEASUREMENT_HAS_SNR                               (1<<0)
-/** A valid 'carrier frequency' is stored in the data structure. */
-#define GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY                 (1<<9)
-/** A valid 'carrier cycles' is stored in the data structure. */
-#define GNSS_MEASUREMENT_HAS_CARRIER_CYCLES                    (1<<10)
-/** A valid 'carrier phase' is stored in the data structure. */
-#define GNSS_MEASUREMENT_HAS_CARRIER_PHASE                     (1<<11)
-/** A valid 'carrier phase uncertainty' is stored in the data structure. */
-#define GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY         (1<<12)
 
 /* The following typedef together with its constants below are deprecated, and
  * will be removed in the next release. */
@@ -331,12 +208,6 @@
  * indicator.
  */
 typedef uint8_t GnssMultipathIndicator;
-/** The indicator is not available or unknown. */
-#define GNSS_MULTIPATH_INDICATOR_UNKNOWN                 0
-/** The measurement is indicated to be affected by multipath. */
-#define GNSS_MULTIPATH_INDICATOR_PRESENT                 1
-/** The measurement is indicated to be not affected by multipath. */
-#define GNSS_MULTIPATH_INDICATOR_NOT_PRESENT             2
 
 /* The following typedef together with its constants below are deprecated, and
  * will be removed in the next release. */
@@ -363,21 +234,6 @@
  * set to GNSS_MEASUREMENT_STATE_UNKNOWN(0).
  */
 typedef uint32_t GnssMeasurementState;
-#define GNSS_MEASUREMENT_STATE_UNKNOWN                   0
-#define GNSS_MEASUREMENT_STATE_CODE_LOCK             (1<<0)
-#define GNSS_MEASUREMENT_STATE_BIT_SYNC              (1<<1)
-#define GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC         (1<<2)
-#define GNSS_MEASUREMENT_STATE_TOW_DECODED           (1<<3)
-#define GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS        (1<<4)
-#define GNSS_MEASUREMENT_STATE_SYMBOL_SYNC           (1<<5)
-#define GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC       (1<<6)
-#define GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED       (1<<7)
-#define GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC       (1<<8)
-#define GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC  (1<<9)
-#define GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK    (1<<10)
-#define GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK (1<<11)
-#define GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC     (1<<12)
-#define GNSS_MEASUREMENT_STATE_SBAS_SYNC             (1<<13)
 
 /* The following typedef together with its constants below are deprecated, and
  * will be removed in the next release. */
@@ -391,10 +247,6 @@
  * Flags indicating the Accumulated Delta Range's states.
  */
 typedef uint16_t GnssAccumulatedDeltaRangeState;
-#define GNSS_ADR_STATE_UNKNOWN                       0
-#define GNSS_ADR_STATE_VALID                     (1<<0)
-#define GNSS_ADR_STATE_RESET                     (1<<1)
-#define GNSS_ADR_STATE_CYCLE_SLIP                (1<<2)
 
 /* The following typedef together with its constants below are deprecated, and
  * will be removed in the next release. */
@@ -414,26 +266,6 @@
  */
 typedef int16_t GnssNavigationMessageType;
 
-#define GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN       0
-/** GPS L1 C/A message contained in the structure.  */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L1CA      0x0101
-/** GPS L2-CNAV message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L2CNAV    0x0102
-/** GPS L5-CNAV message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_L5CNAV    0x0103
-/** GPS CNAV-2 message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_GPS_CNAV2     0x0104
-/** Glonass L1 CA message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_GLO_L1CA      0x0301
-/** Beidou D1 message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_BDS_D1        0x0501
-/** Beidou D2 message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_BDS_D2        0x0502
-/** Galileo I/NAV message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_GAL_I         0x0601
-/** Galileo F/NAV message contained in the structure. */
-#define GNSS_NAVIGATION_MESSAGE_TYPE_GAL_F         0x0602
-
 /**
  * Status of Navigation Message
  * When a message is received properly without any parity error in its navigation words, the
@@ -444,9 +276,6 @@
  * corrected.
  */
 typedef uint16_t NavigationMessageStatus;
-#define NAV_MESSAGE_STATUS_UNKNOWN              0
-#define NAV_MESSAGE_STATUS_PARITY_PASSED   (1<<0)
-#define NAV_MESSAGE_STATUS_PARITY_REBUILT  (1<<1)
 
 /* This constant is deprecated, and will be removed in the next release. */
 #define NAV_MESSAGE_STATUS_UNKONW              0
@@ -455,22 +284,11 @@
  * Flags that indicate information about the satellite
  */
 typedef uint8_t                                 GnssSvFlags;
-#define GNSS_SV_FLAGS_NONE                      0
-#define GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA        (1 << 0)
-#define GNSS_SV_FLAGS_HAS_ALMANAC_DATA          (1 << 1)
-#define GNSS_SV_FLAGS_USED_IN_FIX               (1 << 2)
 
 /**
  * Constellation type of GnssSvInfo
  */
 typedef uint8_t                         GnssConstellationType;
-#define GNSS_CONSTELLATION_UNKNOWN      0
-#define GNSS_CONSTELLATION_GPS          1
-#define GNSS_CONSTELLATION_SBAS         2
-#define GNSS_CONSTELLATION_GLONASS      3
-#define GNSS_CONSTELLATION_QZSS         4
-#define GNSS_CONSTELLATION_BEIDOU       5
-#define GNSS_CONSTELLATION_GALILEO      6
 
 /**
  * Name for the GPS XTRA interface.
@@ -522,7 +340,6 @@
  */
 #define GNSS_CONFIGURATION_INTERFACE     "gnss_configuration"
 
-
 /** Represents a location. */
 typedef struct {
     /** set to sizeof(GpsLocation) */
@@ -1126,9 +943,6 @@
     const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev);
 };
 
-#define AGPS_RIL_REQUEST_SETID_IMSI     (1<<0L)
-#define AGPS_RIL_REQUEST_SETID_MSISDN   (1<<1L)
-
 #define AGPS_RIL_REQUEST_REFLOC_CELLID  (1<<0L)
 #define AGPS_RIL_REQUEST_REFLOC_MAC     (1<<1L)
 
@@ -1251,19 +1065,6 @@
  * subsystem knows about the Geofence.
  *
  */
-#define GPS_GEOFENCE_ENTERED     (1<<0L)
-#define GPS_GEOFENCE_EXITED      (1<<1L)
-#define GPS_GEOFENCE_UNCERTAIN   (1<<2L)
-
-#define GPS_GEOFENCE_UNAVAILABLE (1<<0L)
-#define GPS_GEOFENCE_AVAILABLE   (1<<1L)
-
-#define GPS_GEOFENCE_OPERATION_SUCCESS           0
-#define GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES -100
-#define GPS_GEOFENCE_ERROR_ID_EXISTS          -101
-#define GPS_GEOFENCE_ERROR_ID_UNKNOWN         -102
-#define GPS_GEOFENCE_ERROR_INVALID_TRANSITION -103
-#define GPS_GEOFENCE_ERROR_GENERIC            -149
 
 /**
  * The callback associated with the geofence.
@@ -1972,10 +1773,6 @@
     gnss_measurement_callback gnss_measurement_callback;
 } GpsMeasurementCallbacks;
 
-#define GPS_MEASUREMENT_OPERATION_SUCCESS          0
-#define GPS_MEASUREMENT_ERROR_ALREADY_INIT      -100
-#define GPS_MEASUREMENT_ERROR_GENERIC           -101
-
 /**
  * Extended interface for GPS Measurements support.
  */
@@ -2147,10 +1944,6 @@
     gnss_navigation_message_callback gnss_navigation_message_callback;
 } GpsNavigationMessageCallbacks;
 
-#define GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS             0
-#define GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT         -100
-#define GPS_NAVIGATION_MESSAGE_ERROR_GENERIC              -101
-
 /**
  * Extended interface for GPS navigation message reporting support.
  */
diff --git a/include/hardware/gralloc.h b/include/hardware/gralloc.h
index 779915c..1b06ebf 100644
--- a/include/hardware/gralloc.h
+++ b/include/hardware/gralloc.h
@@ -68,69 +68,69 @@
 
 enum {
     /* buffer is never read in software */
-    GRALLOC_USAGE_SW_READ_NEVER         = 0x00000000,
+    GRALLOC_USAGE_SW_READ_NEVER         = 0x00000000U,
     /* buffer is rarely read in software */
-    GRALLOC_USAGE_SW_READ_RARELY        = 0x00000002,
+    GRALLOC_USAGE_SW_READ_RARELY        = 0x00000002U,
     /* buffer is often read in software */
-    GRALLOC_USAGE_SW_READ_OFTEN         = 0x00000003,
+    GRALLOC_USAGE_SW_READ_OFTEN         = 0x00000003U,
     /* mask for the software read values */
-    GRALLOC_USAGE_SW_READ_MASK          = 0x0000000F,
+    GRALLOC_USAGE_SW_READ_MASK          = 0x0000000FU,
 
     /* buffer is never written in software */
-    GRALLOC_USAGE_SW_WRITE_NEVER        = 0x00000000,
+    GRALLOC_USAGE_SW_WRITE_NEVER        = 0x00000000U,
     /* buffer is rarely written in software */
-    GRALLOC_USAGE_SW_WRITE_RARELY       = 0x00000020,
+    GRALLOC_USAGE_SW_WRITE_RARELY       = 0x00000020U,
     /* buffer is often written in software */
-    GRALLOC_USAGE_SW_WRITE_OFTEN        = 0x00000030,
+    GRALLOC_USAGE_SW_WRITE_OFTEN        = 0x00000030U,
     /* mask for the software write values */
-    GRALLOC_USAGE_SW_WRITE_MASK         = 0x000000F0,
+    GRALLOC_USAGE_SW_WRITE_MASK         = 0x000000F0U,
 
     /* buffer will be used as an OpenGL ES texture */
-    GRALLOC_USAGE_HW_TEXTURE            = 0x00000100,
+    GRALLOC_USAGE_HW_TEXTURE            = 0x00000100U,
     /* buffer will be used as an OpenGL ES render target */
-    GRALLOC_USAGE_HW_RENDER             = 0x00000200,
+    GRALLOC_USAGE_HW_RENDER             = 0x00000200U,
     /* buffer will be used by the 2D hardware blitter */
-    GRALLOC_USAGE_HW_2D                 = 0x00000400,
+    GRALLOC_USAGE_HW_2D                 = 0x00000400U,
     /* buffer will be used by the HWComposer HAL module */
-    GRALLOC_USAGE_HW_COMPOSER           = 0x00000800,
+    GRALLOC_USAGE_HW_COMPOSER           = 0x00000800U,
     /* buffer will be used with the framebuffer device */
-    GRALLOC_USAGE_HW_FB                 = 0x00001000,
+    GRALLOC_USAGE_HW_FB                 = 0x00001000U,
 
     /* buffer should be displayed full-screen on an external display when
      * possible */
-    GRALLOC_USAGE_EXTERNAL_DISP         = 0x00002000,
+    GRALLOC_USAGE_EXTERNAL_DISP         = 0x00002000U,
 
     /* Must have a hardware-protected path to external display sink for
      * this buffer.  If a hardware-protected path is not available, then
      * either don't composite only this buffer (preferred) to the
      * external sink, or (less desirable) do not route the entire
      * composition to the external sink.  */
-    GRALLOC_USAGE_PROTECTED             = 0x00004000,
+    GRALLOC_USAGE_PROTECTED             = 0x00004000U,
 
     /* buffer may be used as a cursor */
-    GRALLOC_USAGE_CURSOR                = 0x00008000,
+    GRALLOC_USAGE_CURSOR                = 0x00008000U,
 
     /* buffer will be used with the HW video encoder */
-    GRALLOC_USAGE_HW_VIDEO_ENCODER      = 0x00010000,
+    GRALLOC_USAGE_HW_VIDEO_ENCODER      = 0x00010000U,
     /* buffer will be written by the HW camera pipeline */
-    GRALLOC_USAGE_HW_CAMERA_WRITE       = 0x00020000,
+    GRALLOC_USAGE_HW_CAMERA_WRITE       = 0x00020000U,
     /* buffer will be read by the HW camera pipeline */
-    GRALLOC_USAGE_HW_CAMERA_READ        = 0x00040000,
+    GRALLOC_USAGE_HW_CAMERA_READ        = 0x00040000U,
     /* buffer will be used as part of zero-shutter-lag queue */
-    GRALLOC_USAGE_HW_CAMERA_ZSL         = 0x00060000,
+    GRALLOC_USAGE_HW_CAMERA_ZSL         = 0x00060000U,
     /* mask for the camera access values */
-    GRALLOC_USAGE_HW_CAMERA_MASK        = 0x00060000,
+    GRALLOC_USAGE_HW_CAMERA_MASK        = 0x00060000U,
     /* mask for the software usage bit-mask */
-    GRALLOC_USAGE_HW_MASK               = 0x00071F00,
+    GRALLOC_USAGE_HW_MASK               = 0x00071F00U,
 
     /* buffer will be used as a RenderScript Allocation */
-    GRALLOC_USAGE_RENDERSCRIPT          = 0x00100000,
+    GRALLOC_USAGE_RENDERSCRIPT          = 0x00100000U,
 
     /* Set by the consumer to indicate to the producer that they may attach a
      * buffer that they did not detach from the BufferQueue. Will be filtered
      * out by GRALLOC_USAGE_ALLOC_MASK, so gralloc modules will not need to
      * handle this flag. */
-    GRALLOC_USAGE_FOREIGN_BUFFERS       = 0x00200000,
+    GRALLOC_USAGE_FOREIGN_BUFFERS       = 0x00200000U,
 
     /* Mask of all flags which could be passed to a gralloc module for buffer
      * allocation. Any flags not in this mask do not need to be handled by
@@ -138,11 +138,11 @@
     GRALLOC_USAGE_ALLOC_MASK            = ~(GRALLOC_USAGE_FOREIGN_BUFFERS),
 
     /* implementation-specific private usage flags */
-    GRALLOC_USAGE_PRIVATE_0             = 0x10000000,
-    GRALLOC_USAGE_PRIVATE_1             = 0x20000000,
-    GRALLOC_USAGE_PRIVATE_2             = 0x40000000,
-    GRALLOC_USAGE_PRIVATE_3             = 0x80000000,
-    GRALLOC_USAGE_PRIVATE_MASK          = 0xF0000000,
+    GRALLOC_USAGE_PRIVATE_0             = 0x10000000U,
+    GRALLOC_USAGE_PRIVATE_1             = 0x20000000U,
+    GRALLOC_USAGE_PRIVATE_2             = 0x40000000U,
+    GRALLOC_USAGE_PRIVATE_3             = 0x80000000U,
+    GRALLOC_USAGE_PRIVATE_MASK          = 0xF0000000U,
 };
 
 /*****************************************************************************/
@@ -372,7 +372,7 @@
 static inline int gralloc_open(const struct hw_module_t* module, 
         struct alloc_device_t** device) {
     return module->methods->open(module, 
-            GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);
+            GRALLOC_HARDWARE_GPU0, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int gralloc_close(struct alloc_device_t* device) {
diff --git a/include/hardware/gralloc1.h b/include/hardware/gralloc1.h
index 58c0e33..4845010 100644
--- a/include/hardware/gralloc1.h
+++ b/include/hardware/gralloc1.h
@@ -36,7 +36,19 @@
      * allocate may be NULL, which instructs the device to report whether the
      * given allocation is possible or not. */
     GRALLOC1_CAPABILITY_TEST_ALLOCATE = 1,
-    GRALLOC1_LAST_CAPABILITY = 1,
+
+    /* If this capability is supported, then the implementation supports
+     * allocating buffers with more than one image layer. */
+    GRALLOC1_CAPABILITY_LAYERED_BUFFERS = 2,
+
+    /* If this capability is supported, then the implementation always closes
+     * and deletes a buffer handle whenever the last reference is removed.
+     *
+     * Supporting this capability is strongly recommended.  It will become
+     * mandatory in future releases. */
+    GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE = 3,
+
+    GRALLOC1_LAST_CAPABILITY = 3,
 } gralloc1_capability_t;
 
 typedef enum {
@@ -71,7 +83,7 @@
     GRALLOC1_CONSUMER_USAGE_FOREIGN_BUFFERS = 1ULL << 21,
 
     /* 1ULL << 22 */
-    /* 1ULL << 23 */
+    GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER = 1ULL << 23,
     /* 1ULL << 24 */
     /* 1ULL << 25 */
     /* 1ULL << 26 */
@@ -141,7 +153,9 @@
     GRALLOC1_FUNCTION_LOCK = 18,
     GRALLOC1_FUNCTION_LOCK_FLEX = 19,
     GRALLOC1_FUNCTION_UNLOCK = 20,
-    GRALLOC1_LAST_FUNCTION = 20,
+    GRALLOC1_FUNCTION_SET_LAYER_COUNT = 21,
+    GRALLOC1_FUNCTION_GET_LAYER_COUNT = 22,
+    GRALLOC1_LAST_FUNCTION = 22,
 } gralloc1_function_descriptor_t;
 
 typedef enum {
@@ -188,7 +202,7 @@
     /* 1ULL << 20 */
     /* 1ULL << 21 */
     GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER = 1ULL << 22,
-    /* 1ULL << 23 */
+    GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA = 1ULL << 23,
     /* 1ULL << 24 */
     /* 1ULL << 25 */
     /* 1ULL << 26 */
@@ -290,7 +304,7 @@
 static inline int gralloc1_open(const struct hw_module_t* module,
         gralloc1_device_t** device) {
     return module->methods->open(module, GRALLOC_HARDWARE_MODULE_ID,
-            (struct hw_device_t**) device);
+            TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int gralloc1_close(gralloc1_device_t* device) {
@@ -440,6 +454,30 @@
         gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
         int32_t /*android_pixel_format_t*/ format);
 
+/* setLayerCount(..., layerCount)
+ * Function descriptor: GRALLOC1_FUNCTION_SET_LAYER_COUNT
+ * Must be provided by all gralloc1 devices that provide the
+ * GRALLOC1_CAPABILITY_LAYERED_BUFFERS capability.
+ *
+ * Sets the number of layers in the buffer.
+ *
+ * A buffer with multiple layers may be used as the backing store of an array
+ * texture. All layers of a buffer share the same characteristics (e.g.,
+ * dimensions, format, usage). Devices that do not support
+ * GRALLOC1_CAPABILITY_LAYERED_BUFFERS must allocate only buffers with a single
+ * layer.
+ *
+ * Parameters:
+ *   layerCount - the desired number of layers, must be non-zero
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ *   GRALLOC1_ERROR_BAD_DESCRIPTOR - the buffer descriptor is invalid
+ *   GRALLOC1_ERROR_BAD_VALUE - the layer count is invalid
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_LAYER_COUNT)(
+        gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
+        uint32_t layerCount);
+
 /* setProducerUsage(..., usage)
  * Function descriptor: GRALLOC1_FUNCTION_SET_PRODUCER_USAGE
  * Must be provided by all gralloc1 devices
@@ -564,6 +602,28 @@
         gralloc1_device_t* device, buffer_handle_t descriptor,
         int32_t* outFormat);
 
+/* getLayerCount(..., outLayerCount)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_LAYER_COUNT
+ * Must be provided by all gralloc1 devices that provide the
+ * GRALLOC1_CAPABILITY_LAYERED_BUFFERS capability.
+ *
+ * Gets the number of layers of the buffer.
+ *
+ * See setLayerCount for more information about this value.
+ *
+ * Parameters:
+ *   outLayerCount - the number of layers in the image, must be non-NULL
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ *   GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ *   GRALLOC1_ERROR_UNSUPPORTED - the device is unable to retrieve the
+ *       layer count from the buffer; see note [1] in this section's header for
+ *       more information
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_LAYER_COUNT)(
+        gralloc1_device_t* device, buffer_handle_t buffer,
+        uint32_t* outLayerCount);
+
 /* getProducerUsage(..., outUsage)
  * Function descriptor: GRALLOC1_FUNCTION_GET_PRODUCER_USAGE
  * Must be provided by all gralloc1 devices
@@ -696,6 +756,12 @@
  * referring to a particular backing store is freed, that backing store should
  * also be freed.
  *
+ * When GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE is supported,
+ * native_handle_close and native_handle_delete must always be called by the
+ * implementation whenever the last reference is removed.  Otherwise, a call
+ * to release() will be followed by native_handle_close and native_handle_delete
+ * by the caller when the buffer is not allocated locally through allocate().
+ *
  * Parameters:
  *   buffer - the buffer from which a reference should be removed
  *
diff --git a/include/hardware/hardware.h b/include/hardware/hardware.h
index 74f57aa..5ba37e9 100644
--- a/include/hardware/hardware.h
+++ b/include/hardware/hardware.h
@@ -20,8 +20,10 @@
 #include <stdint.h>
 #include <sys/cdefs.h>
 
+#ifndef _HW_DONT_INCLUDE_CORE_
 #include <cutils/native_handle.h>
 #include <system/graphics.h>
+#endif // _HW_DONT_INCLUDE_CORE_
 
 __BEGIN_DECLS
 
@@ -201,6 +203,12 @@
 
 } hw_device_t;
 
+#ifdef __cplusplus
+#define TO_HW_DEVICE_T_OPEN(x) reinterpret_cast<struct hw_device_t**>(x)
+#else
+#define TO_HW_DEVICE_T_OPEN(x) (struct hw_device_t**)(x)
+#endif
+
 /**
  * Name of the hal_module_info
  */
diff --git a/include/hardware/hdmi_cec.h b/include/hardware/hdmi_cec.h
index ab70f92..aa06384 100644
--- a/include/hardware/hdmi_cec.h
+++ b/include/hardware/hdmi_cec.h
@@ -417,7 +417,7 @@
 static inline int hdmi_cec_open(const struct hw_module_t* module,
         struct hdmi_cec_device** device) {
     return module->methods->open(module,
-            HDMI_CEC_HARDWARE_INTERFACE, (struct hw_device_t**)device);
+            HDMI_CEC_HARDWARE_INTERFACE, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int hdmi_cec_close(struct hdmi_cec_device* device) {
diff --git a/include/hardware/hwcomposer.h b/include/hardware/hwcomposer.h
index 61218bb..9eb1aaf 100644
--- a/include/hardware/hwcomposer.h
+++ b/include/hardware/hwcomposer.h
@@ -481,6 +481,7 @@
     struct hw_module_t common;
 } hwc_module_t;
 
+#define HWC_ERROR (-1)
 typedef struct hwc_composer_device_1 {
     /**
      * Common methods of the hardware composer device.  This *must* be the first member of
@@ -714,9 +715,9 @@
      * (*getActiveConfig)() returns the index of the configuration that is
      * currently active on the connected display. The index is relative to
      * the list of configuration handles returned by getDisplayConfigs. If there
-     * is no active configuration, -1 shall be returned.
+     * is no active configuration, HWC_ERROR shall be returned.
      *
-     * Returns the configuration index on success or -1 on error.
+     * Returns the configuration index on success or HWC_ERROR on error.
      *
      * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_4 and later.
      * It shall be NULL for previous versions.
@@ -783,7 +784,7 @@
 static inline int hwc_open_1(const struct hw_module_t* module,
         hwc_composer_device_1_t** device) {
     return module->methods->open(module,
-            HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device);
+            HWC_HARDWARE_COMPOSER, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int hwc_close_1(hwc_composer_device_1_t* device) {
diff --git a/include/hardware/hwcomposer2.h b/include/hardware/hwcomposer2.h
index 6973603..d5a0d6f 100644
--- a/include/hardware/hwcomposer2.h
+++ b/include/hardware/hwcomposer2.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_HARDWARE_HWCOMPOSER2_H
 #define ANDROID_HARDWARE_HWCOMPOSER2_H
 
+#include <sys/cdefs.h>
+
 #include <hardware/hardware.h>
 
 #include "hwcomposer_defs.h"
@@ -92,6 +94,16 @@
      * the client. This will prevent the client from applying the color
      * transform during its composition step. */
     HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM = 2,
+
+    /* Specifies that the present fence must not be used as an accurate
+     * representation of the actual present time of a frame.
+     * This capability must never be set by HWC2 devices.
+     * This capability may be set for HWC1 devices that use the
+     * HWC2On1Adapter where emulation of the present fence using the retire
+     * fence is not feasible.
+     * In the future, CTS tests will require present time to be reliable.
+     */
+    HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE = 3,
 } hwc2_capability_t;
 
 /* Possible composition types for a given layer */
@@ -333,6 +345,8 @@
         case HWC2_CAPABILITY_SIDEBAND_STREAM: return "SidebandStream";
         case HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM:
                 return "SkipClientColorTransform";
+        case HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE:
+                return "PresentFenceIsNotReliable";
         default: return "Unknown";
     }
 }
@@ -360,7 +374,7 @@
 
 static inline const char* getDisplayRequestName(
         hwc2_display_request_t request) {
-    switch (request) {
+    switch (__BIONIC_CAST(static_cast, int, request)) {
         case 0: return "None";
         case HWC2_DISPLAY_REQUEST_FLIP_CLIENT_TARGET: return "FlipClientTarget";
         case HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT:
@@ -459,7 +473,7 @@
 }
 
 static inline const char* getLayerRequestName(hwc2_layer_request_t request) {
-    switch (request) {
+    switch (__BIONIC_CAST(static_cast, int, request)) {
         case 0: return "None";
         case HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET: return "ClearClientTarget";
         default: return "Unknown";
@@ -477,7 +491,7 @@
 }
 
 static inline const char* getTransformName(hwc_transform_t transform) {
-    switch (transform) {
+    switch (__BIONIC_CAST(static_cast, int, transform)) {
         case 0: return "None";
         case HWC_TRANSFORM_FLIP_H: return "FlipH";
         case HWC_TRANSFORM_FLIP_V: return "FlipV";
@@ -549,6 +563,7 @@
     Invalid = HWC2_CAPABILITY_INVALID,
     SidebandStream = HWC2_CAPABILITY_SIDEBAND_STREAM,
     SkipClientColorTransform = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM,
+    PresentFenceIsNotReliable = HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE,
 };
 TO_STRING(hwc2_capability_t, Capability, getCapabilityName)
 
@@ -738,7 +753,7 @@
 static inline int hwc2_open(const struct hw_module_t* module,
         hwc2_device_t** device) {
     return module->methods->open(module, HWC_HARDWARE_COMPOSER,
-            (struct hw_device_t**) device);
+            TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int hwc2_close(hwc2_device_t* device) {
diff --git a/include/hardware/hwcomposer_defs.h b/include/hardware/hwcomposer_defs.h
index 18b30bc..1e81e6e 100644
--- a/include/hardware/hwcomposer_defs.h
+++ b/include/hardware/hwcomposer_defs.h
@@ -136,9 +136,9 @@
  */
 enum {
     /*
-     * HWC_SKIP_LAYER is set by SurfaceFlnger to indicate that the HAL
+     * HWC_SKIP_LAYER is set by SurfaceFlinger to indicate that the HAL
      * shall not consider this layer for composition as it will be handled
-     * by SurfaceFlinger (just as if compositionType was set to HWC_OVERLAY).
+     * by SurfaceFlinger (just as if compositionType was set to HWC_FRAMEBUFFER).
      */
     HWC_SKIP_LAYER = 0x00000001,
 
diff --git a/include/hardware/keymaster0.h b/include/hardware/keymaster0.h
index f020e5b..52ac64b 100644
--- a/include/hardware/keymaster0.h
+++ b/include/hardware/keymaster0.h
@@ -134,7 +134,7 @@
         keymaster0_device_t** device)
 {
     int rc = module->methods->open(module, KEYSTORE_KEYMASTER,
-            (struct hw_device_t**) device);
+            TO_HW_DEVICE_T_OPEN(device));
 
     return rc;
 }
diff --git a/include/hardware/keymaster1.h b/include/hardware/keymaster1.h
index afd202c..9969380 100644
--- a/include/hardware/keymaster1.h
+++ b/include/hardware/keymaster1.h
@@ -536,7 +536,7 @@
 /* Convenience API for opening and closing keymaster devices */
 
 static inline int keymaster1_open(const struct hw_module_t* module, keymaster1_device_t** device) {
-    return module->methods->open(module, KEYSTORE_KEYMASTER, (struct hw_device_t**)device);
+    return module->methods->open(module, KEYSTORE_KEYMASTER, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int keymaster1_close(keymaster1_device_t* device) {
diff --git a/include/hardware/keymaster2.h b/include/hardware/keymaster2.h
index 565ad2e..f1993f8 100644
--- a/include/hardware/keymaster2.h
+++ b/include/hardware/keymaster2.h
@@ -420,7 +420,7 @@
 /* Convenience API for opening and closing keymaster devices */
 
 static inline int keymaster2_open(const struct hw_module_t* module, keymaster2_device_t** device) {
-    return module->methods->open(module, KEYSTORE_KEYMASTER, (struct hw_device_t**)device);
+    return module->methods->open(module, KEYSTORE_KEYMASTER, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int keymaster2_close(keymaster2_device_t* device) {
diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h
index 0f9bc27..7d1b348 100644
--- a/include/hardware/keymaster_defs.h
+++ b/include/hardware/keymaster_defs.h
@@ -135,6 +135,26 @@
     KM_TAG_OS_PATCHLEVEL = KM_UINT | 706,          /* Patch level of system (keymaster2) */
     KM_TAG_UNIQUE_ID = KM_BYTES | 707,             /* Used to provide unique ID in attestation */
     KM_TAG_ATTESTATION_CHALLENGE = KM_BYTES | 708, /* Used to provide challenge in attestation */
+    KM_TAG_ATTESTATION_APPLICATION_ID = KM_BYTES | 709, /* Used to identify the set of possible
+                                                         * applications of which one has initiated
+                                                         * a key attestation */
+    KM_TAG_ATTESTATION_ID_BRAND = KM_BYTES | 710,  /* Used to provide the device's brand name to be
+                                                      included in attestation */
+    KM_TAG_ATTESTATION_ID_DEVICE = KM_BYTES | 711, /* Used to provide the device's device name to be
+                                                      included in attestation */
+    KM_TAG_ATTESTATION_ID_PRODUCT = KM_BYTES | 712, /* Used to provide the device's product name to
+                                                       be included in attestation */
+    KM_TAG_ATTESTATION_ID_SERIAL = KM_BYTES | 713, /* Used to provide the device's serial number to
+                                                      be included in attestation */
+    KM_TAG_ATTESTATION_ID_IMEI = KM_BYTES | 714,   /* Used to provide the device's IMEI to be
+                                                      included in attestation */
+    KM_TAG_ATTESTATION_ID_MEID = KM_BYTES | 715,   /* Used to provide the device's MEID to be
+                                                      included in attestation */
+    KM_TAG_ATTESTATION_ID_MANUFACTURER = KM_BYTES | 716, /* Used to provide the device's
+                                                            manufacturer name to be included in
+                                                            attestation */
+    KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717,  /* Used to provide the device's model name to be
+                                                      included in attestation */
 
     /* Tags used only to provide data to or receive data from operations */
     KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000, /* Used to provide associated data for AEAD modes. */
@@ -427,6 +447,8 @@
     KM_ERROR_KEY_REQUIRES_UPGRADE = -62,
     KM_ERROR_ATTESTATION_CHALLENGE_MISSING = -63,
     KM_ERROR_KEYMASTER_NOT_CONFIGURED = -64,
+    KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING = -65,
+    KM_ERROR_CANNOT_ATTEST_IDS = -66,
 
     KM_ERROR_UNIMPLEMENTED = -100,
     KM_ERROR_VERSION_MISMATCH = -101,
diff --git a/include/hardware/local_time_hal.h b/include/hardware/local_time_hal.h
index 946e799..1bbbf11 100644
--- a/include/hardware/local_time_hal.h
+++ b/include/hardware/local_time_hal.h
@@ -109,7 +109,7 @@
         struct local_time_hw_device** device)
 {
     return module->methods->open(module, LOCAL_TIME_HARDWARE_INTERFACE,
-                                 (struct hw_device_t**)device);
+                                 TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int local_time_hw_device_close(struct local_time_hw_device* device)
diff --git a/include/hardware/nfc-base.h b/include/hardware/nfc-base.h
new file mode 100644
index 0000000..6b63ad2
--- /dev/null
+++ b/include/hardware/nfc-base.h
@@ -0,0 +1,34 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+// Source: android.hardware.nfc@1.0
+// Root: android.hardware:hardware/interfaces
+
+#ifndef HIDL_GENERATED_ANDROID_HARDWARE_NFC_V1_0_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_ANDROID_HARDWARE_NFC_V1_0_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+    HAL_NFC_OPEN_CPLT_EVT = 0u, // 0
+    HAL_NFC_CLOSE_CPLT_EVT = 1u, // 1
+    HAL_NFC_POST_INIT_CPLT_EVT = 2u, // 2
+    HAL_NFC_PRE_DISCOVER_CPLT_EVT = 3u, // 3
+    HAL_NFC_REQUEST_CONTROL_EVT = 4u, // 4
+    HAL_NFC_RELEASE_CONTROL_EVT = 5u, // 5
+    HAL_NFC_ERROR_EVT = 6u, // 6
+};
+
+enum {
+    HAL_NFC_STATUS_OK = 0u, // 0
+    HAL_NFC_STATUS_FAILED = 1u, // 1
+    HAL_NFC_STATUS_ERR_TRANSPORT = 2u, // 2
+    HAL_NFC_STATUS_ERR_CMD_TIMEOUT = 3u, // 3
+    HAL_NFC_STATUS_REFUSED = 4u, // 4
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // HIDL_GENERATED_ANDROID_HARDWARE_NFC_V1_0_EXPORTED_CONSTANTS_H_
diff --git a/include/hardware/nfc.h b/include/hardware/nfc.h
index 58d33d9..fdd79a5 100644
--- a/include/hardware/nfc.h
+++ b/include/hardware/nfc.h
@@ -23,6 +23,7 @@
 #include <sys/types.h>
 
 #include <hardware/hardware.h>
+#include "nfc-base.h"
 
 __BEGIN_DECLS
 
@@ -69,34 +70,9 @@
     struct hw_module_t common;
 } nfc_nci_module_t;
 
-/*
- * HAL events that can be passed back to the stack
- */
 typedef uint8_t nfc_event_t;
-
-enum {
-    HAL_NFC_OPEN_CPLT_EVT           = 0x00,
-    HAL_NFC_CLOSE_CPLT_EVT          = 0x01,
-    HAL_NFC_POST_INIT_CPLT_EVT      = 0x02,
-    HAL_NFC_PRE_DISCOVER_CPLT_EVT   = 0x03,
-    HAL_NFC_REQUEST_CONTROL_EVT     = 0x04,
-    HAL_NFC_RELEASE_CONTROL_EVT     = 0x05,
-    HAL_NFC_ERROR_EVT               = 0x06
-};
-
-/*
- * Allowed status return values for each of the HAL methods
- */
 typedef uint8_t nfc_status_t;
 
-enum {
-    HAL_NFC_STATUS_OK               = 0x00,
-    HAL_NFC_STATUS_FAILED           = 0x01,
-    HAL_NFC_STATUS_ERR_TRANSPORT    = 0x02,
-    HAL_NFC_STATUS_ERR_CMD_TIMEOUT  = 0x03,
-    HAL_NFC_STATUS_REFUSED          = 0x04
-};
-
 /*
  * The callback passed in from the NFC stack that the HAL
  * can use to pass events back to the stack.
diff --git a/include/hardware/nvram.h b/include/hardware/nvram.h
index a1868b5..0654afe 100644
--- a/include/hardware/nvram.h
+++ b/include/hardware/nvram.h
@@ -21,6 +21,7 @@
 #include <sys/cdefs.h>
 
 #include <hardware/hardware.h>
+#include <hardware/nvram_defs.h>
 
 __BEGIN_DECLS
 
@@ -30,30 +31,7 @@
 
 /* The version of this module. */
 #define NVRAM_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1)
-#define NVRAM_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION(0, 1)
-
-/* Values returned by nvram_device methods. */
-typedef uint32_t nvram_result_t;
-
-const nvram_result_t NV_RESULT_SUCCESS = 0;
-const nvram_result_t NV_RESULT_INTERNAL_ERROR = 1;
-const nvram_result_t NV_RESULT_ACCESS_DENIED = 2;
-const nvram_result_t NV_RESULT_INVALID_PARAMETER = 3;
-const nvram_result_t NV_RESULT_SPACE_DOES_NOT_EXIST = 4;
-const nvram_result_t NV_RESULT_SPACE_ALREADY_EXISTS = 5;
-const nvram_result_t NV_RESULT_OPERATION_DISABLED = 6;
-
-/* Values describing available access controls. */
-typedef uint32_t nvram_control_t;
-
-const nvram_control_t NV_CONTROL_PERSISTENT_WRITE_LOCK = 1;
-const nvram_control_t NV_CONTROL_BOOT_WRITE_LOCK = 2;
-const nvram_control_t NV_CONTROL_BOOT_READ_LOCK = 3;
-const nvram_control_t NV_CONTROL_WRITE_AUTHORIZATION = 4;
-const nvram_control_t NV_CONTROL_READ_AUTHORIZATION = 5;
-const nvram_control_t NV_CONTROL_WRITE_EXTEND = 6;
-
-const uint32_t NV_UNLIMITED_SPACES = 0xFFFFFFFF;
+#define NVRAM_DEVICE_API_VERSION_1_1 HARDWARE_DEVICE_API_VERSION(1, 1)
 
 struct nvram_module {
     /**
@@ -99,6 +77,17 @@
         const struct nvram_device* device, uint64_t* available_size);
 
     /**
+     * Outputs the maximum number of bytes that can be allocated for a single
+     * space. This will always be at least 32. If an implementation does not
+     * limit the maximum size it may provide the total size.
+     *
+     *   device - The nvram_device instance.
+     *   max_space_size - Receives the output. Cannot be NULL.
+     */
+    nvram_result_t (*get_max_space_size_in_bytes)(
+        const struct nvram_device* device, uint64_t* max_space_size);
+
+    /**
      * Outputs the maximum total number of spaces that may be allocated.
      * This will always be at least 8. Outputs NV_UNLIMITED_SPACES if any
      * number of spaces are supported (limited only to available NVRAM
@@ -337,7 +326,7 @@
 static inline int nvram_open(const struct hw_module_t* module,
                              nvram_device_t** device) {
     return module->methods->open(module, NVRAM_HARDWARE_DEVICE_ID,
-                                 (struct hw_device_t**)device);
+                                 TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int nvram_close(nvram_device_t* device) {
diff --git a/include/hardware/nvram_defs.h b/include/hardware/nvram_defs.h
new file mode 100644
index 0000000..0256a3c
--- /dev/null
+++ b/include/hardware/nvram_defs.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file contains data type definitions and constants that are useful to
+ * code interacting with and implementing the NVRAM HAL, even though it doesn't
+ * use the actual NVRAM HAL module interface. Keeping this in a separate file
+ * simplifies inclusion in low-level code which can't easily include the heavier
+ * hardware.h due to lacking standard headers.
+ */
+
+#ifndef ANDROID_HARDWARE_NVRAM_DEFS_H
+#define ANDROID_HARDWARE_NVRAM_DEFS_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+/* Values returned by nvram_device methods. */
+typedef uint32_t nvram_result_t;
+
+const nvram_result_t NV_RESULT_SUCCESS = 0;
+const nvram_result_t NV_RESULT_INTERNAL_ERROR = 1;
+const nvram_result_t NV_RESULT_ACCESS_DENIED = 2;
+const nvram_result_t NV_RESULT_INVALID_PARAMETER = 3;
+const nvram_result_t NV_RESULT_SPACE_DOES_NOT_EXIST = 4;
+const nvram_result_t NV_RESULT_SPACE_ALREADY_EXISTS = 5;
+const nvram_result_t NV_RESULT_OPERATION_DISABLED = 6;
+
+/* Values describing available access controls. */
+typedef uint32_t nvram_control_t;
+
+const nvram_control_t NV_CONTROL_PERSISTENT_WRITE_LOCK = 1;
+const nvram_control_t NV_CONTROL_BOOT_WRITE_LOCK = 2;
+const nvram_control_t NV_CONTROL_BOOT_READ_LOCK = 3;
+const nvram_control_t NV_CONTROL_WRITE_AUTHORIZATION = 4;
+const nvram_control_t NV_CONTROL_READ_AUTHORIZATION = 5;
+const nvram_control_t NV_CONTROL_WRITE_EXTEND = 6;
+
+const uint32_t NV_UNLIMITED_SPACES = 0xFFFFFFFF;
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // ANDROID_HARDWARE_NVRAM_DEFS_H
diff --git a/include/hardware/qemu_pipe.h b/include/hardware/qemu_pipe.h
deleted file mode 100644
index 53aec97..0000000
--- a/include/hardware/qemu_pipe.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
-#define ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
-
-#include <sys/cdefs.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <pthread.h>  /* for pthread_once() */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#ifndef D
-#  define  D(...)   do{}while(0)
-#endif
-
-/* Try to open a new Qemu fast-pipe. This function returns a file descriptor
- * that can be used to communicate with a named service managed by the
- * emulator.
- *
- * This file descriptor can be used as a standard pipe/socket descriptor.
- *
- * 'pipeName' is the name of the emulator service you want to connect to.
- * E.g. 'opengles' or 'camera'.
- *
- * On success, return a valid file descriptor
- * Returns -1 on error, and errno gives the error code, e.g.:
- *
- *    EINVAL  -> unknown/unsupported pipeName
- *    ENOSYS  -> fast pipes not available in this system.
- *
- * ENOSYS should never happen, except if you're trying to run within a
- * misconfigured emulator.
- *
- * You should be able to open several pipes to the same pipe service,
- * except for a few special cases (e.g. GSM modem), where EBUSY will be
- * returned if more than one client tries to connect to it.
- */
-static __inline__ int
-qemu_pipe_open(const char*  pipeName)
-{
-    char  buff[256];
-    int   buffLen;
-    int   fd, ret;
-
-    if (pipeName == NULL || pipeName[0] == '\0') {
-        errno = EINVAL;
-        return -1;
-    }
-
-    snprintf(buff, sizeof buff, "pipe:%s", pipeName);
-
-    fd = open("/dev/qemu_pipe", O_RDWR);
-    if (fd < 0 && errno == ENOENT)
-        fd = open("/dev/goldfish_pipe", O_RDWR);
-    if (fd < 0) {
-        D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno));
-        //errno = ENOSYS;
-        return -1;
-    }
-
-    buffLen = strlen(buff);
-
-    ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1));
-    if (ret != buffLen+1) {
-        D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno));
-        if (ret == 0) {
-            errno = ECONNRESET;
-        } else if (ret > 0) {
-            errno = EINVAL;
-        }
-        return -1;
-    }
-
-    return fd;
-}
-
-#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_PIPE_H */
diff --git a/include/hardware/qemud.h b/include/hardware/qemud.h
deleted file mode 100644
index 5c39f9c..0000000
--- a/include/hardware/qemud.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_INCLUDE_HARDWARE_QEMUD_H
-#define ANDROID_INCLUDE_HARDWARE_QEMUD_H
-
-#include <cutils/sockets.h>
-#include "qemu_pipe.h"
-
-/* the following is helper code that is used by the QEMU-specific
- * hardware HAL modules to communicate with the emulator program
- * through the 'qemud' multiplexing daemon, or through the qemud
- * pipe.
- *
- * see the documentation comments for details in
- * development/emulator/qemud/qemud.c
- *
- * all definitions here are built into the HAL module to avoid
- * having to write a tiny shared library for this.
- */
-
-/* we expect the D macro to be defined to a function macro
- * that sends its formatted string argument(s) to the log.
- * If not, ignore the traces.
- */
-#ifndef D
-#  define  D(...)  ((void)0)
-#endif
-
-static __inline__ int
-qemud_fd_write(int  fd, const void*  buff, int  len)
-{
-    int  len2;
-    do {
-        len2 = write(fd, buff, len);
-    } while (len2 < 0 && errno == EINTR);
-    return len2;
-}
-
-static __inline__ int
-qemud_fd_read(int  fd, void*  buff, int  len)
-{
-    int  len2;
-    do {
-        len2 = read(fd, buff, len);
-    } while (len2 < 0 && errno == EINTR);
-    return len2;
-}
-
-static __inline__ int
-qemud_channel_open(const char*  name)
-{
-    int  fd;
-    int  namelen = strlen(name);
-    char answer[2];
-    char pipe_name[256];
-
-    /* First, try to connect to the pipe. */
-    snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", name);
-    fd = qemu_pipe_open(pipe_name);
-    if (fd < 0) {
-        D("QEMUD pipe is not available for %s: %s", name, strerror(errno));
-        /* If pipe is not available, connect to qemud control socket */
-        fd = socket_local_client( "qemud",
-                                  ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                  SOCK_STREAM );
-        if (fd < 0) {
-            D("no qemud control socket: %s", strerror(errno));
-            return -1;
-        }
-
-        /* send service name to connect */
-        if (qemud_fd_write(fd, name, namelen) != namelen) {
-            D("can't send service name to qemud: %s",
-               strerror(errno));
-            close(fd);
-            return -1;
-        }
-
-        /* read answer from daemon */
-        if (qemud_fd_read(fd, answer, 2) != 2 ||
-            answer[0] != 'O' || answer[1] != 'K') {
-            D("cant' connect to %s service through qemud", name);
-            close(fd);
-            return -1;
-        }
-    }
-    return fd;
-}
-
-static __inline__ int
-qemud_channel_send(int  fd, const void*  msg, int  msglen)
-{
-    char  header[5];
-
-    if (msglen < 0)
-        msglen = strlen((const char*)msg);
-
-    if (msglen == 0)
-        return 0;
-
-    snprintf(header, sizeof header, "%04x", msglen);
-    if (qemud_fd_write(fd, header, 4) != 4) {
-        D("can't write qemud frame header: %s", strerror(errno));
-        return -1;
-    }
-
-    if (qemud_fd_write(fd, msg, msglen) != msglen) {
-        D("can4t write qemud frame payload: %s", strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static __inline__ int
-qemud_channel_recv(int  fd, void*  msg, int  msgsize)
-{
-    char  header[5];
-    int   size, avail;
-
-    if (qemud_fd_read(fd, header, 4) != 4) {
-        D("can't read qemud frame header: %s", strerror(errno));
-        return -1;
-    }
-    header[4] = 0;
-    if (sscanf(header, "%04x", &size) != 1) {
-        D("malformed qemud frame header: '%.*s'", 4, header);
-        return -1;
-    }
-    if (size > msgsize)
-        return -1;
-
-    if (qemud_fd_read(fd, msg, size) != size) {
-        D("can't read qemud frame payload: %s", strerror(errno));
-        return -1;
-    }
-    return size;
-}
-
-#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_H */
diff --git a/include/hardware/radio.h b/include/hardware/radio.h
index 145deb5..413f413 100644
--- a/include/hardware/radio.h
+++ b/include/hardware/radio.h
@@ -285,7 +285,7 @@
                                        struct radio_hw_device** device)
 {
     return module->methods->open(module, RADIO_HARDWARE_DEVICE,
-                                 (struct hw_device_t**)device);
+                                 TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int radio_hw_device_close(const struct radio_hw_device* device)
diff --git a/include/hardware/sensors-base.h b/include/hardware/sensors-base.h
new file mode 100644
index 0000000..b0f6223
--- /dev/null
+++ b/include/hardware/sensors-base.h
@@ -0,0 +1,137 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+// Source: android.hardware.sensors@1.0
+// Root: android.hardware:hardware/interfaces
+
+#ifndef HIDL_GENERATED_ANDROID_HARDWARE_SENSORS_V1_0_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_ANDROID_HARDWARE_SENSORS_V1_0_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+    SENSOR_HAL_NORMAL_MODE = 0,
+    SENSOR_HAL_DATA_INJECTION_MODE = 1,
+};
+
+enum {
+    SENSOR_TYPE_META_DATA = 0,
+    SENSOR_TYPE_ACCELEROMETER = 1,
+    SENSOR_TYPE_MAGNETIC_FIELD = 2,
+    SENSOR_TYPE_ORIENTATION = 3,
+    SENSOR_TYPE_GYROSCOPE = 4,
+    SENSOR_TYPE_LIGHT = 5,
+    SENSOR_TYPE_PRESSURE = 6,
+    SENSOR_TYPE_TEMPERATURE = 7,
+    SENSOR_TYPE_PROXIMITY = 8,
+    SENSOR_TYPE_GRAVITY = 9,
+    SENSOR_TYPE_LINEAR_ACCELERATION = 10,
+    SENSOR_TYPE_ROTATION_VECTOR = 11,
+    SENSOR_TYPE_RELATIVE_HUMIDITY = 12,
+    SENSOR_TYPE_AMBIENT_TEMPERATURE = 13,
+    SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14,
+    SENSOR_TYPE_GAME_ROTATION_VECTOR = 15,
+    SENSOR_TYPE_GYROSCOPE_UNCALIBRATED = 16,
+    SENSOR_TYPE_SIGNIFICANT_MOTION = 17,
+    SENSOR_TYPE_STEP_DETECTOR = 18,
+    SENSOR_TYPE_STEP_COUNTER = 19,
+    SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20,
+    SENSOR_TYPE_HEART_RATE = 21,
+    SENSOR_TYPE_TILT_DETECTOR = 22,
+    SENSOR_TYPE_WAKE_GESTURE = 23,
+    SENSOR_TYPE_GLANCE_GESTURE = 24,
+    SENSOR_TYPE_PICK_UP_GESTURE = 25,
+    SENSOR_TYPE_WRIST_TILT_GESTURE = 26,
+    SENSOR_TYPE_DEVICE_ORIENTATION = 27,
+    SENSOR_TYPE_POSE_6DOF = 28,
+    SENSOR_TYPE_STATIONARY_DETECT = 29,
+    SENSOR_TYPE_MOTION_DETECT = 30,
+    SENSOR_TYPE_HEART_BEAT = 31,
+    SENSOR_TYPE_DYNAMIC_SENSOR_META = 32,
+    SENSOR_TYPE_ADDITIONAL_INFO = 33,
+    SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT = 34,
+    SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED = 35,
+    SENSOR_TYPE_DEVICE_PRIVATE_BASE = 65536, // 0x10000
+};
+
+enum {
+    SENSOR_FLAG_WAKE_UP = 1u, // 1
+    SENSOR_FLAG_CONTINUOUS_MODE = 0u, // 0
+    SENSOR_FLAG_ON_CHANGE_MODE = 2u, // 2
+    SENSOR_FLAG_ONE_SHOT_MODE = 4u, // 4
+    SENSOR_FLAG_SPECIAL_REPORTING_MODE = 6u, // 6
+    SENSOR_FLAG_DATA_INJECTION = 16u, // 0x10
+    SENSOR_FLAG_DYNAMIC_SENSOR = 32u, // 0x20
+    SENSOR_FLAG_ADDITIONAL_INFO = 64u, // 0x40
+    SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM = 1024u, // 0x400
+    SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC = 2048u, // 0x800
+    SENSOR_FLAG_MASK_REPORTING_MODE = 14u, // 0xE
+    SENSOR_FLAG_MASK_DIRECT_REPORT = 896u, // 0x380
+    SENSOR_FLAG_MASK_DIRECT_CHANNEL = 3072u, // 0xC00
+};
+
+typedef enum {
+    SENSOR_FLAG_SHIFT_REPORTING_MODE = 1,
+    SENSOR_FLAG_SHIFT_DATA_INJECTION = 4,
+    SENSOR_FLAG_SHIFT_DYNAMIC_SENSOR = 5,
+    SENSOR_FLAG_SHIFT_ADDITIONAL_INFO = 6,
+    SENSOR_FLAG_SHIFT_DIRECT_REPORT = 7,
+    SENSOR_FLAG_SHIFT_DIRECT_CHANNEL = 10,
+} sensor_flag_shift_t;
+
+enum {
+    SENSOR_STATUS_NO_CONTACT = -1, // (-1)
+    SENSOR_STATUS_UNRELIABLE = 0,
+    SENSOR_STATUS_ACCURACY_LOW = 1,
+    SENSOR_STATUS_ACCURACY_MEDIUM = 2,
+    SENSOR_STATUS_ACCURACY_HIGH = 3,
+};
+
+enum {
+    META_DATA_FLUSH_COMPLETE = 1u, // 1
+};
+
+typedef enum {
+    AINFO_BEGIN = 0u, // 0
+    AINFO_END = 1u, // 1
+    AINFO_UNTRACKED_DELAY = 65536u, // 0x10000
+    AINFO_INTERNAL_TEMPERATURE = 65537u, // 65537
+    AINFO_VEC3_CALIBRATION = 65538u, // 65538
+    AINFO_SENSOR_PLACEMENT = 65539u, // 65539
+    AINFO_SAMPLING = 65540u, // 65540
+    AINFO_CHANNEL_NOISE = 131072u, // 0x20000
+    AINFO_CHANNEL_SAMPLER = 131073u, // 131073
+    AINFO_CHANNEL_FILTER = 131074u, // 131074
+    AINFO_CHANNEL_LINEAR_TRANSFORM = 131075u, // 131075
+    AINFO_CHANNEL_NONLINEAR_MAP = 131076u, // 131076
+    AINFO_CHANNEL_RESAMPLER = 131077u, // 131077
+    AINFO_LOCAL_GEOMAGNETIC_FIELD = 196608u, // 0x30000
+    AINFO_LOCAL_GRAVITY = 196609u, // 196609
+    AINFO_DOCK_STATE = 196610u, // 196610
+    AINFO_HIGH_PERFORMANCE_MODE = 196611u, // 196611
+    AINFO_MAGNETIC_FIELD_CALIBRATION = 196612u, // 196612
+    AINFO_CUSTOM_START = 268435456u, // 0x10000000
+    AINFO_DEBUGGING_START = 1073741824u, // 0x40000000
+} additional_info_type_t;
+
+typedef enum {
+    SENSOR_DIRECT_RATE_STOP = 0,
+    SENSOR_DIRECT_RATE_NORMAL = 1,
+    SENSOR_DIRECT_RATE_FAST = 2,
+    SENSOR_DIRECT_RATE_VERY_FAST = 3,
+} direct_rate_level_t;
+
+typedef enum {
+    SENSOR_DIRECT_MEM_TYPE_ASHMEM = 1,
+    SENSOR_DIRECT_MEM_TYPE_GRALLOC = 2,
+} direct_mem_type_t;
+
+typedef enum {
+    SENSOR_DIRECT_FMT_SENSORS_EVENT = 1,
+} direct_format_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // HIDL_GENERATED_ANDROID_HARDWARE_SENSORS_V1_0_EXPORTED_CONSTANTS_H_
diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h
index 1d73c31..dde997f 100644
--- a/include/hardware/sensors.h
+++ b/include/hardware/sensors.h
@@ -24,6 +24,8 @@
 #include <hardware/hardware.h>
 #include <cutils/native_handle.h>
 
+#include "sensors-base.h"
+
 __BEGIN_DECLS
 
 /*****************************************************************************/
@@ -54,14 +56,15 @@
 #define SENSORS_HARDWARE_POLL       "poll"
 
 /**
- * Handles must be higher than SENSORS_HANDLE_BASE and must be unique.
- * A Handle identifies a given sensors. The handle is used to activate
- * and/or deactivate sensors.
- * In this version of the API there can only be 256 handles.
+ * Sensor handle is greater than 0 and less than INT32_MAX.
+ *
+ * **** Deprecated ****
+ * Defined values below are kept for code compatibility. Note sensor handle can be as large as
+ * INT32_MAX.
  */
 #define SENSORS_HANDLE_BASE             0
-#define SENSORS_HANDLE_BITS             8
-#define SENSORS_HANDLE_COUNT            (1<<SENSORS_HANDLE_BITS)
+#define SENSORS_HANDLE_BITS             31
+#define SENSORS_HANDLE_COUNT            (1ull<<SENSORS_HANDLE_BITS)
 
 
 /*
@@ -82,7 +85,7 @@
  */
 enum {
     /* a previous flush operation has completed */
-    META_DATA_FLUSH_COMPLETE = 1,
+    // META_DATA_FLUSH_COMPLETE = 1,
     META_DATA_VERSION   /* always last, leave auto-assigned */
 };
 
@@ -94,27 +97,11 @@
 #define SENSOR_PERMISSION_BODY_SENSORS "android.permission.BODY_SENSORS"
 
 /*
- * Availability: SENSORS_DEVICE_API_VERSION_1_4
- * Sensor HAL modes used in set_operation_mode method
+ * sensor flags legacy names
+ *
+ * please use SENSOR_FLAG_* directly for new implementation.
+ * @see sensor_t
  */
-enum {
-    /*
-     * Operating modes for the HAL.
-     */
-
-    /*
-     * Normal mode operation. This is the default state of operation.
-     * The HAL shall initialize into this mode on device startup.
-     */
-    SENSOR_HAL_NORMAL_MODE        = 0,
-
-    /*
-     * Data Injection mode. In this mode, the device shall not source data from the
-     * physical sensors as it would in normal mode. Instead sensor data is
-     * injected by the sensor service.
-     */
-    SENSOR_HAL_DATA_INJECTION_MODE      = 0x1
-};
 
 #define SENSOR_FLAG_MASK(nbit, shift)   (((1<<(nbit))-1)<<(shift))
 #define SENSOR_FLAG_MASK_1(shift)       SENSOR_FLAG_MASK(1, shift)
@@ -122,746 +109,82 @@
 /*
  * Mask and shift for reporting mode sensor flags defined above.
  */
-#define REPORTING_MODE_SHIFT            (1)
+#define REPORTING_MODE_SHIFT            SENSOR_FLAG_SHIFT_REPORTING_MODE
 #define REPORTING_MODE_NBIT             (3)
-#define REPORTING_MODE_MASK             SENSOR_FLAG_MASK(REPORTING_MODE_NBIT, REPORTING_MODE_SHIFT)
-                                        // 0xE
+#define REPORTING_MODE_MASK             SENSOR_FLAG_MASK_REPORTING_MODE
 
 /*
  * Mask and shift for data_injection mode sensor flags defined above.
  */
-#define DATA_INJECTION_SHIFT            (4)
-#define DATA_INJECTION_MASK             SENSOR_FLAG_MASK_1(DATA_INJECTION_SHIFT) //0x10
+#define DATA_INJECTION_SHIFT            SENSOR_FLAG_SHIFT_DATA_INJECTION
+#define DATA_INJECTION_MASK             SENSOR_FLAG_DATA_INJECTION
 
 /*
  * Mask and shift for dynamic sensor flag.
  */
-#define DYNAMIC_SENSOR_SHIFT            (5)
-#define DYNAMIC_SENSOR_MASK             SENSOR_FLAG_MASK_1(DYNAMIC_SENSOR_SHIFT) //0x20
+#define DYNAMIC_SENSOR_SHIFT            SENSOR_FLAG_SHIFT_DYNAMIC_SENSOR
+#define DYNAMIC_SENSOR_MASK             SENSOR_FLAG_DYNAMIC_SENSOR
 
 /*
  * Mask and shift for sensor additional information support.
  */
-#define ADDITIONAL_INFO_SHIFT           (6)
-#define ADDITIONAL_INFO_MASK            SENSOR_FLAG_MASK_1(ADDITIONAL_INFO_SHIFT) //0x40
+#define ADDITIONAL_INFO_SHIFT           SENSOR_FLAG_SHIFT_ADDITIONAL_INFO
+#define ADDITIONAL_INFO_MASK            SENSOR_FLAG_ADDITIONAL_INFO
 
 /*
- * Availability: SENSORS_DEVICE_API_VERSION_1_3
- * Sensor flags used in sensor_t.flags.
+ * Legacy alias of SENSOR_TYPE_MAGNETIC_FIELD.
+ *
+ * Previously, the type of a sensor measuring local magnetic field is named
+ * SENSOR_TYPE_GEOMAGNETIC_FIELD and SENSOR_TYPE_MAGNETIC_FIELD is its alias.
+ * SENSOR_TYPE_MAGNETIC_FIELD is redefined as primary name to avoid confusion.
+ * SENSOR_TYPE_GEOMAGNETIC_FIELD is the alias and is deprecating. New implementation must not use
+ * SENSOR_TYPE_GEOMAGNETIC_FIELD.
  */
-enum {
-    /*
-     * Whether this sensor wakes up the AP from suspend mode when data is available.  Whenever
-     * sensor events are delivered from a wake_up sensor, the driver needs to hold a wake_lock till
-     * the events are read by the SensorService i.e till sensors_poll_device_t.poll() is called the
-     * next time. Once poll is called again it means events have been read by the SensorService, the
-     * driver can safely release the wake_lock. SensorService will continue to hold a wake_lock till
-     * the app actually reads the events.
-     */
-    SENSOR_FLAG_WAKE_UP = 1U << 0,
-    /*
-     * Reporting modes for various sensors. Each sensor will have exactly one of these modes set.
-     * The least significant 2nd, 3rd and 4th bits are used to represent four possible reporting
-     * modes.
-     */
-    SENSOR_FLAG_CONTINUOUS_MODE        = 0,    // 0000
-    SENSOR_FLAG_ON_CHANGE_MODE         = 0x2,  // 0010
-    SENSOR_FLAG_ONE_SHOT_MODE          = 0x4,  // 0100
-    SENSOR_FLAG_SPECIAL_REPORTING_MODE = 0x6,  // 0110
-
-    /*
-     * Set this flag if the sensor supports data_injection mode and allows data to be injected
-     * from the SensorService. When in data_injection ONLY sensors with this flag set are injected
-     * sensor data and only sensors with this flag set are activated. Eg: Accelerometer and Step
-     * Counter sensors can be set with this flag and SensorService will inject accelerometer data
-     * and read the corresponding step counts.
-     */
-    SENSOR_FLAG_SUPPORTS_DATA_INJECTION = DATA_INJECTION_MASK, // 1 0000
-
-    /*
-     * Set this flag if the sensor is a dynamically connected sensor. See
-     * dynamic_sensor_meta_event_t and SENSOR_TYPE_DYNAMIC_SENSOR_META for details.
-     */
-    SENSOR_FLAG_DYNAMIC_SENSOR = DYNAMIC_SENSOR_MASK,
-
-    /*
-     * Set this flag if sensor additional information is supported. See SENSOR_TYPE_ADDITIONAL_INFO
-     * and additional_info_event_t for details.
-     */
-    SENSOR_FLAG_ADDITIONAL_INFO = ADDITIONAL_INFO_MASK
-};
-
+#define SENSOR_TYPE_GEOMAGNETIC_FIELD   SENSOR_TYPE_MAGNETIC_FIELD
 
 /*
- * Sensor type
+ * Sensor string types for Android defined sensor types.
  *
- * Each sensor has a type which defines what this sensor measures and how
- * measures are reported. See the Base sensors and Composite sensors lists
- * for complete descriptions:
- * http://source.android.com/devices/sensors/base_triggers.html
- * http://source.android.com/devices/sensors/composite_sensors.html
+ * For Android defined sensor types, string type will be override in sensor service and thus no
+ * longer needed to be added to sensor_t data structure.
  *
- * Device manufacturers (OEMs) can define their own sensor types, for
- * their private use by applications or services provided by them. Such
- * sensor types are specific to an OEM and can't be exposed in the SDK.
- * These types must start at SENSOR_TYPE_DEVICE_PRIVATE_BASE.
- *
- * All sensors defined outside of the device private range must correspond to
- * a type defined in this file, and must satisfy the characteristics listed in
- * the description of the sensor type.
- *
- * Starting with version SENSORS_DEVICE_API_VERSION_1_2, each sensor also
- * has a stringType.
- *  - StringType of sensors inside of the device private range MUST be prefixed
- *    by the sensor provider's or OEM reverse domain name. In particular, they
- *    cannot use the "android.sensor" prefix.
- *  - StringType of sensors outside of the device private range MUST correspond
- *    to the one defined in this file (starting with "android.sensor").
- *    For example, accelerometers must have
- *      type=SENSOR_TYPE_ACCELEROMETER and
- *      stringType=SENSOR_STRING_TYPE_ACCELEROMETER
- *
- * When android introduces a new sensor type that can replace an OEM-defined
- * sensor type, the OEM must use the official sensor type and stringType on
- * versions of the HAL that support this new official sensor type.
- *
- * Example (made up): Suppose Google's Glass team wants to surface a sensor
- * detecting that Glass is on a head.
- *  - Such a sensor is not officially supported in android KitKat
- *  - Glass devices launching on KitKat can implement a sensor with
- *    type = 0x10001 and stringType = "com.google.glass.onheaddetector"
- *  - In L android release, if android decides to define
- *    SENSOR_TYPE_ON_HEAD_DETECTOR and STRING_SENSOR_TYPE_ON_HEAD_DETECTOR,
- *    those types should replace the Glass-team-specific types in all future
- *    launches.
- *  - When launching Glass on the L release, Google should now use the official
- *    type (SENSOR_TYPE_ON_HEAD_DETECTOR) and stringType.
- *  - This way, all applications can now use this sensor.
+ * These definitions are going to be removed soon.
  */
-
-/*
- * Base for device manufacturers private sensor types.
- * These sensor types can't be exposed in the SDK.
- */
-#define SENSOR_TYPE_DEVICE_PRIVATE_BASE     0x10000
-
-/*
- * SENSOR_TYPE_META_DATA
- * reporting-mode: n/a
- * wake-up sensor: n/a
- *
- * NO SENSOR OF THAT TYPE MUST BE RETURNED (*get_sensors_list)()
- *
- * SENSOR_TYPE_META_DATA is a special token used to populate the
- * sensors_meta_data_event structure. It doesn't correspond to a physical
- * sensor. sensors_meta_data_event are special, they exist only inside
- * the HAL and are generated spontaneously, as opposed to be related to
- * a physical sensor.
- *
- *   sensors_meta_data_event_t.version must be META_DATA_VERSION
- *   sensors_meta_data_event_t.sensor must be 0
- *   sensors_meta_data_event_t.type must be SENSOR_TYPE_META_DATA
- *   sensors_meta_data_event_t.reserved must be 0
- *   sensors_meta_data_event_t.timestamp must be 0
- *
- * The payload is a meta_data_event_t, where:
- * meta_data_event_t.what can take the following values:
- *
- * META_DATA_FLUSH_COMPLETE
- *   This event indicates that a previous (*flush)() call has completed for the sensor
- *   handle specified in meta_data_event_t.sensor.
- *   see (*flush)() for more details
- *
- * All other values for meta_data_event_t.what are reserved and
- * must not be used.
- *
- */
-#define SENSOR_TYPE_META_DATA                        (0)
-
-/*
-  * Wake up sensors.
-  * Each sensor may have either or both a wake-up and a non-wake variant.
-  * When registered in batch mode, wake-up sensors will wake up the AP when
-  * their FIFOs are full or when the batch timeout expires. A separate FIFO has
-  * to be maintained for wake up sensors and non wake up sensors. The non wake-up
-  * sensors need to overwrite their FIFOs when they are full till the AP wakes up
-  * and the wake-up sensors will wake-up the AP when their FIFOs are full or when
-  * the batch timeout expires without losing events. Wake-up and non wake-up variants
-  * of each sensor can be activated at different rates independently of each other.
-  *
-  * Note: Proximity sensor and significant motion sensor which were defined in previous
-  * releases are also wake-up sensors and should be treated as such. Wake-up one-shot
-  * sensors like SIGNIFICANT_MOTION cannot be batched, hence the text about batch above
-  * doesn't apply to them. See the definitions of SENSOR_TYPE_PROXIMITY and
-  * SENSOR_TYPE_SIGNIFICANT_MOTION for more info.
-  *
-  * Set SENSOR_FLAG_WAKE_UP flag for all wake-up sensors.
-  *
-  * For example, A device can have two sensors both of SENSOR_TYPE_ACCELEROMETER and
-  * one of them can be a wake_up sensor (with SENSOR_FLAG_WAKE_UP flag set) and the other
-  * can be a regular non wake_up sensor. Both of these sensors must be activated/deactivated
-  * independently of the other.
-  */
-
-/*
- * SENSOR_TYPE_ACCELEROMETER
- * reporting-mode: continuous
- *
- *  All values are in SI units (m/s^2) and measure the acceleration of the
- *  device minus the force of gravity.
- *
- *  Implement the non-wake-up version of this sensor and implement the wake-up
- *  version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_ACCELEROMETER                    (1)
-#define SENSOR_STRING_TYPE_ACCELEROMETER             "android.sensor.accelerometer"
-
-/*
- * SENSOR_TYPE_GEOMAGNETIC_FIELD
- * reporting-mode: continuous
- *
- *  All values are in micro-Tesla (uT) and measure the geomagnetic
- *  field in the X, Y and Z axis.
- *
- *  Implement the non-wake-up version of this sensor and implement the wake-up
- *  version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_GEOMAGNETIC_FIELD                (2)
-#define SENSOR_TYPE_MAGNETIC_FIELD  SENSOR_TYPE_GEOMAGNETIC_FIELD
-#define SENSOR_STRING_TYPE_MAGNETIC_FIELD            "android.sensor.magnetic_field"
-
-/*
- * SENSOR_TYPE_ORIENTATION
- * reporting-mode: continuous
- *
- * All values are angles in degrees.
- *
- * Orientation sensors return sensor events for all 3 axes at a constant
- * rate defined by setDelay().
- *
- * Implement the non-wake-up version of this sensor and implement the wake-up
- * version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_ORIENTATION                      (3)
-#define SENSOR_STRING_TYPE_ORIENTATION               "android.sensor.orientation"
-
-/*
- * SENSOR_TYPE_GYROSCOPE
- * reporting-mode: continuous
- *
- *  All values are in radians/second and measure the rate of rotation
- *  around the X, Y and Z axis.
- *
- *  Implement the non-wake-up version of this sensor and implement the wake-up
- *  version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_GYROSCOPE                        (4)
-#define SENSOR_STRING_TYPE_GYROSCOPE                 "android.sensor.gyroscope"
-
-/*
- * SENSOR_TYPE_LIGHT
- * reporting-mode: on-change
- *
- * The light sensor value is returned in SI lux units.
- *
- * Both wake-up and non wake-up versions are useful.
- */
-#define SENSOR_TYPE_LIGHT                            (5)
-#define SENSOR_STRING_TYPE_LIGHT                     "android.sensor.light"
-
-/*
- * SENSOR_TYPE_PRESSURE
- * reporting-mode: continuous
- *
- * The pressure sensor return the athmospheric pressure in hectopascal (hPa)
- *
- * Implement the non-wake-up version of this sensor and implement the wake-up
- * version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_PRESSURE                         (6)
-#define SENSOR_STRING_TYPE_PRESSURE                  "android.sensor.pressure"
-
-/* SENSOR_TYPE_TEMPERATURE is deprecated in the HAL */
-#define SENSOR_TYPE_TEMPERATURE                      (7)
-#define SENSOR_STRING_TYPE_TEMPERATURE               "android.sensor.temperature"
-
-/*
- * SENSOR_TYPE_PROXIMITY
- * reporting-mode: on-change
- *
- * The proximity sensor which turns the screen off and back on during calls is the
- * wake-up proximity sensor. Implement wake-up proximity sensor before implementing
- * a non wake-up proximity sensor. For the wake-up proximity sensor set the flag
- * SENSOR_FLAG_WAKE_UP.
- * The value corresponds to the distance to the nearest object in centimeters.
- */
-#define SENSOR_TYPE_PROXIMITY                        (8)
-#define SENSOR_STRING_TYPE_PROXIMITY                 "android.sensor.proximity"
-
-/*
- * SENSOR_TYPE_GRAVITY
- * reporting-mode: continuous
- *
- * A gravity output indicates the direction of and magnitude of gravity in
- * the devices's coordinates.
- *
- * Implement the non-wake-up version of this sensor and implement the wake-up
- * version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_GRAVITY                          (9)
-#define SENSOR_STRING_TYPE_GRAVITY                   "android.sensor.gravity"
-
-/*
- * SENSOR_TYPE_LINEAR_ACCELERATION
- * reporting-mode: continuous
- *
- * Indicates the linear acceleration of the device in device coordinates,
- * not including gravity.
- *
- * Implement the non-wake-up version of this sensor and implement the wake-up
- * version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_LINEAR_ACCELERATION             (10)
-#define SENSOR_STRING_TYPE_LINEAR_ACCELERATION      "android.sensor.linear_acceleration"
-
-
-/*
- * SENSOR_TYPE_ROTATION_VECTOR
- * reporting-mode: continuous
- *
- * The rotation vector symbolizes the orientation of the device relative to the
- * East-North-Up coordinates frame.
- *
- * Implement the non-wake-up version of this sensor and implement the wake-up
- * version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_ROTATION_VECTOR                 (11)
-#define SENSOR_STRING_TYPE_ROTATION_VECTOR          "android.sensor.rotation_vector"
-
-/*
- * SENSOR_TYPE_RELATIVE_HUMIDITY
- * reporting-mode: on-change
- *
- * A relative humidity sensor measures relative ambient air humidity and
- * returns a value in percent.
- *
- * Both wake-up and non wake-up versions are useful.
- */
-#define SENSOR_TYPE_RELATIVE_HUMIDITY               (12)
-#define SENSOR_STRING_TYPE_RELATIVE_HUMIDITY        "android.sensor.relative_humidity"
-
-/*
- * SENSOR_TYPE_AMBIENT_TEMPERATURE
- * reporting-mode: on-change
- *
- * The ambient (room) temperature in degree Celsius.
- *
- * Both wake-up and non wake-up versions are useful.
- */
-#define SENSOR_TYPE_AMBIENT_TEMPERATURE             (13)
-#define SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE      "android.sensor.ambient_temperature"
-
-/*
- * SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
- * reporting-mode: continuous
- *
- *  Similar to SENSOR_TYPE_MAGNETIC_FIELD, but the hard iron calibration is
- *  reported separately instead of being included in the measurement.
- *
- *  Implement the non-wake-up version of this sensor and implement the wake-up
- *  version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED     (14)
-#define SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED "android.sensor.magnetic_field_uncalibrated"
-
-/*
- * SENSOR_TYPE_GAME_ROTATION_VECTOR
- * reporting-mode: continuous
- *
- *  Similar to SENSOR_TYPE_ROTATION_VECTOR, but not using the geomagnetic
- *  field.
- *
- *  Implement the non-wake-up version of this sensor and implement the wake-up
- *  version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_GAME_ROTATION_VECTOR            (15)
-#define SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR     "android.sensor.game_rotation_vector"
-
-/*
- * SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
- * reporting-mode: continuous
- *
- *  All values are in radians/second and measure the rate of rotation
- *  around the X, Y and Z axis.
- *
- *  Implement the non-wake-up version of this sensor and implement the wake-up
- *  version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_GYROSCOPE_UNCALIBRATED          (16)
-#define SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED   "android.sensor.gyroscope_uncalibrated"
-
-/*
- * SENSOR_TYPE_SIGNIFICANT_MOTION
- * reporting-mode: one-shot
- *
- * A sensor of this type triggers an event each time significant motion
- * is detected and automatically disables itself.
- * For Significant Motion sensor to be useful, it must be defined as a
- * wake-up sensor. (set SENSOR_FLAG_WAKE_UP). Implement the wake-up significant motion
- * sensor. A non wake-up version is not useful.
- * The only allowed value to return is 1.0.
- */
-
-#define SENSOR_TYPE_SIGNIFICANT_MOTION              (17)
-#define SENSOR_STRING_TYPE_SIGNIFICANT_MOTION       "android.sensor.significant_motion"
-
-/*
- * SENSOR_TYPE_STEP_DETECTOR
- * reporting-mode: special
- *
- * A sensor of this type triggers an event each time a step is taken
- * by the user. The only allowed value to return is 1.0 and an event
- * is generated for each step.
- *
- * Both wake-up and non wake-up versions are useful.
- */
-
-#define SENSOR_TYPE_STEP_DETECTOR                   (18)
-#define SENSOR_STRING_TYPE_STEP_DETECTOR            "android.sensor.step_detector"
-
-
-/*
- * SENSOR_TYPE_STEP_COUNTER
- * reporting-mode: on-change
- *
- * A sensor of this type returns the number of steps taken by the user since
- * the last reboot while activated. The value is returned as a uint64_t and is
- * reset to zero only on a system / android reboot.
- *
- * Implement the non-wake-up version of this sensor and implement the wake-up
- * version if the system possesses a wake up fifo.
- */
-
-#define SENSOR_TYPE_STEP_COUNTER                    (19)
-#define SENSOR_STRING_TYPE_STEP_COUNTER             "android.sensor.step_counter"
-
-/*
- * SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
- * reporting-mode: continuous
- *
- *  Similar to SENSOR_TYPE_ROTATION_VECTOR, but using a magnetometer instead
- *  of using a gyroscope.
- *
- * Implement the non-wake-up version of this sensor and implement the wake-up
- * version if the system possesses a wake up fifo.
- */
-#define SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR     (20)
-#define SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR "android.sensor.geomagnetic_rotation_vector"
-
-/*
- * SENSOR_TYPE_HEART_RATE
- * reporting-mode: on-change
- *
- *  A sensor of this type returns the current heart rate.
- *  The events contain the current heart rate in beats per minute (BPM) and the
- *  status of the sensor during the measurement. See heart_rate_event_t for more
- *  details.
- *
- *  Because this sensor is on-change, events must be generated when and only
- *  when heart_rate.bpm or heart_rate.status have changed since the last
- *  event. In particular, upon the first activation, unless the device is known
- *  to not be on the body, the status field of the first event must be set to
- *  SENSOR_STATUS_UNRELIABLE. The event should be generated no faster than every
- *  period_ns passed to setDelay() or to batch().
- *  See the definition of the on-change reporting mode for more information.
- *
- *  sensor_t.requiredPermission must be set to SENSOR_PERMISSION_BODY_SENSORS.
- *
- *  Both wake-up and non wake-up versions are useful.
- */
-#define SENSOR_TYPE_HEART_RATE                      (21)
-#define SENSOR_STRING_TYPE_HEART_RATE               "android.sensor.heart_rate"
-
-/*
- * SENSOR_TYPE_WAKE_UP_TILT_DETECTOR
- * reporting-mode: special (setDelay has no impact)
- *
- * A sensor of this type generates an event each time a tilt event is detected. A tilt event
- * should be generated if the direction of the 2-seconds window average gravity changed by at least
- * 35 degrees since the activation or the last trigger of the sensor.
- *     reference_estimated_gravity = average of accelerometer measurements over the first
- *                                 1 second after activation or the estimated gravity at the last
- *                                 trigger.
- *     current_estimated_gravity = average of accelerometer measurements over the last 2 seconds.
- *     trigger when angle (reference_estimated_gravity, current_estimated_gravity) > 35 degrees
- *
- * Large accelerations without a change in phone orientation should not trigger a tilt event.
- * For example, a sharp turn or strong acceleration while driving a car should not trigger a tilt
- * event, even though the angle of the average acceleration might vary by more than 35 degrees.
- *
- * Typically, this sensor is implemented with the help of only an accelerometer. Other sensors can
- * be used as well if they do not increase the power consumption significantly. This is a low power
- * sensor that should allow the AP to go into suspend mode. Do not emulate this sensor in the HAL.
- * Like other wake up sensors, the driver is expected to a hold a wake_lock with a timeout of 200 ms
- * while reporting this event. The only allowed return value is 1.0.
- *
- * Implement only the wake-up version of this sensor.
- */
-#define SENSOR_TYPE_TILT_DETECTOR                      (22)
-#define SENSOR_STRING_TYPE_TILT_DETECTOR               "android.sensor.tilt_detector"
-
-/*
- * SENSOR_TYPE_WAKE_GESTURE
- * reporting-mode: one-shot
- *
- * A sensor enabling waking up the device based on a device specific motion.
- *
- * When this sensor triggers, the device behaves as if the power button was
- * pressed, turning the screen on. This behavior (turning on the screen when
- * this sensor triggers) might be deactivated by the user in the device
- * settings. Changes in settings do not impact the behavior of the sensor:
- * only whether the framework turns the screen on when it triggers.
- *
- * The actual gesture to be detected is not specified, and can be chosen by
- * the manufacturer of the device.
- * This sensor must be low power, as it is likely to be activated 24/7.
- * The only allowed value to return is 1.0.
- *
- * Implement only the wake-up version of this sensor.
- */
-#define SENSOR_TYPE_WAKE_GESTURE                               (23)
-#define SENSOR_STRING_TYPE_WAKE_GESTURE                        "android.sensor.wake_gesture"
-
-/*
- * SENSOR_TYPE_GLANCE_GESTURE
- * reporting-mode: one-shot
- *
- * A sensor enabling briefly turning the screen on to enable the user to
- * glance content on screen based on a specific motion.  The device should
- * turn the screen off after a few moments.
- *
- * When this sensor triggers, the device turns the screen on momentarily
- * to allow the user to glance notifications or other content while the
- * device remains locked in a non-interactive state (dozing). This behavior
- * (briefly turning on the screen when this sensor triggers) might be deactivated
- * by the user in the device settings. Changes in settings do not impact the
- * behavior of the sensor: only whether the framework briefly turns the screen on
- * when it triggers.
- *
- * The actual gesture to be detected is not specified, and can be chosen by
- * the manufacturer of the device.
- * This sensor must be low power, as it is likely to be activated 24/7.
- * The only allowed value to return is 1.0.
- *
- * Implement only the wake-up version of this sensor.
- */
-#define SENSOR_TYPE_GLANCE_GESTURE                             (24)
-#define SENSOR_STRING_TYPE_GLANCE_GESTURE                      "android.sensor.glance_gesture"
-
-/**
- * SENSOR_TYPE_PICK_UP_GESTURE
- * reporting-mode: one-shot
- *
- * A sensor of this type triggers when the device is picked up regardless of wherever is was
- * before (desk, pocket, bag). The only allowed return value is 1.0.
- * This sensor de-activates itself immediately after it triggers.
- *
- * Implement only the wake-up version of this sensor.
- */
-#define SENSOR_TYPE_PICK_UP_GESTURE                            (25)
-#define SENSOR_STRING_TYPE_PICK_UP_GESTURE                     "android.sensor.pick_up_gesture"
-
-/*
- * SENSOR_TYPE_WRIST_TILT_GESTURE
- * trigger-mode: special
- * wake-up sensor: yes
- *
- * A sensor of this type triggers an event each time a tilt of the wrist-worn
- * device is detected.
- *
- * This sensor must be low power, as it is likely to be activated 24/7.
- * The only allowed value to return is 1.0.
- *
- * Implement only the wake-up version of this sensor.
- */
-#define SENSOR_TYPE_WRIST_TILT_GESTURE                         (26)
-#define SENSOR_STRING_TYPE_WRIST_TILT_GESTURE                  "android.sensor.wrist_tilt_gesture"
-
-/*
- * SENSOR_TYPE_DEVICE_ORIENTATION
- * reporting-mode: on-change
- *
- * The current orientation of the device. The value should be reported in the
- * first element of the 'data' member variable in sensors_event_t. The only
- * values that can be reported are (please refer to Android Sensor Coordinate
- * System to understand the X and Y axis direction with respect to default
- * orientation):
- *  - 0: device is in default orientation (Y axis is vertical and points up)
- *  - 1: device is rotated 90 degrees counter-clockwise from default
- *       orientation (X axis is vertical and points up)
- *  - 2: device is rotated 180 degrees from default orientation (Y axis is
- *       vertical and points down)
- *  - 3: device is rotated 90 degrees clockwise from default orientation (X axis
- *       is vertical and points down)
- *
- * Moving the device to an orientation where the Z axis is vertical (either up
- * or down) should not cause a new event to be reported.
- *
- * To improve the user experience of this sensor, it is recommended to implement
- * some physical (i.e., rotation angle) and temporal (i.e., delay) hysteresis.
- * In other words, minor or transient rotations should not cause a new event to
- * be reported.
- *
- * This sensor should only be implemented with the help of an accelerometer.
- * This is a low power sensor that should reduce the number of interrupts of the
- * AP. Do not emulate this sensor in the HAL.
- *
- * Both wake-up and non wake-up versions are useful.
- */
-#define SENSOR_TYPE_DEVICE_ORIENTATION                 (27)
-#define SENSOR_STRING_TYPE_DEVICE_ORIENTATION          "android.sensor.device_orientation"
-
-/*
- * SENSOR_TYPE_POSE_6DOF
- * trigger-mode: continuous
- *
- * A sensor of this type returns the pose of the device.
- * Pose of the device is defined as the orientation of the device from a
- * Earth Centered Earth Fixed frame and the translation from an arbitrary
- * point at subscription.
- *
- * This sensor can be high power. It can use any and all of the following
- *           . Accelerometer
- *           . Gyroscope
- *           . Camera
- *           . Depth Camera
- *
- */
-#define SENSOR_TYPE_POSE_6DOF                         (28)
-#define SENSOR_STRING_TYPE_POSE_6DOF                  "android.sensor.pose_6dof"
-
-/*
- * SENSOR_TYPE_STATIONARY_DETECT
- * trigger mode: one shot
- *
- * A sensor of this type returns an event if the device is still/stationary for
- * a while. The period of time to monitor for statinarity should be greater than
- * 5 seconds, and less than 10 seconds.
- *
- * Stationarity here refers to absolute stationarity. eg: device on desk.
- *
- * The only allowed value to return is 1.0.
- */
-#define SENSOR_TYPE_STATIONARY_DETECT                   (29)
+#define SENSOR_STRING_TYPE_ACCELEROMETER                "android.sensor.accelerometer"
+#define SENSOR_STRING_TYPE_MAGNETIC_FIELD               "android.sensor.magnetic_field"
+#define SENSOR_STRING_TYPE_ORIENTATION                  "android.sensor.orientation"
+#define SENSOR_STRING_TYPE_GYROSCOPE                    "android.sensor.gyroscope"
+#define SENSOR_STRING_TYPE_LIGHT                        "android.sensor.light"
+#define SENSOR_STRING_TYPE_PRESSURE                     "android.sensor.pressure"
+#define SENSOR_STRING_TYPE_TEMPERATURE                  "android.sensor.temperature"
+#define SENSOR_STRING_TYPE_PROXIMITY                    "android.sensor.proximity"
+#define SENSOR_STRING_TYPE_GRAVITY                      "android.sensor.gravity"
+#define SENSOR_STRING_TYPE_LINEAR_ACCELERATION          "android.sensor.linear_acceleration"
+#define SENSOR_STRING_TYPE_ROTATION_VECTOR              "android.sensor.rotation_vector"
+#define SENSOR_STRING_TYPE_RELATIVE_HUMIDITY            "android.sensor.relative_humidity"
+#define SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE          "android.sensor.ambient_temperature"
+#define SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED  "android.sensor.magnetic_field_uncalibrated"
+#define SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR         "android.sensor.game_rotation_vector"
+#define SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED       "android.sensor.gyroscope_uncalibrated"
+#define SENSOR_STRING_TYPE_SIGNIFICANT_MOTION           "android.sensor.significant_motion"
+#define SENSOR_STRING_TYPE_STEP_DETECTOR                "android.sensor.step_detector"
+#define SENSOR_STRING_TYPE_STEP_COUNTER                 "android.sensor.step_counter"
+#define SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR  "android.sensor.geomagnetic_rotation_vector"
+#define SENSOR_STRING_TYPE_HEART_RATE                   "android.sensor.heart_rate"
+#define SENSOR_STRING_TYPE_TILT_DETECTOR                "android.sensor.tilt_detector"
+#define SENSOR_STRING_TYPE_WAKE_GESTURE                 "android.sensor.wake_gesture"
+#define SENSOR_STRING_TYPE_GLANCE_GESTURE               "android.sensor.glance_gesture"
+#define SENSOR_STRING_TYPE_PICK_UP_GESTURE              "android.sensor.pick_up_gesture"
+#define SENSOR_STRING_TYPE_WRIST_TILT_GESTURE           "android.sensor.wrist_tilt_gesture"
+#define SENSOR_STRING_TYPE_DEVICE_ORIENTATION           "android.sensor.device_orientation"
+#define SENSOR_STRING_TYPE_POSE_6DOF                    "android.sensor.pose_6dof"
 #define SENSOR_STRING_TYPE_STATIONARY_DETECT            "android.sensor.stationary_detect"
-
-/*
- * SENSOR_TYPE_MOTION_DETECT
- * trigger mode: one shot
- *
- * A sensor of this type returns an event if the device is not still for
- * a while. The period of time to monitor for statinarity should be greater than
- * 5 seconds, and less than 10 seconds.
- *
- * Motion here refers to any mechanism in which the device is causes to be
- * moved in its inertial frame. eg: Pickin up the device and walking with it
- * to a nearby room may trigger motion wherewas keeping the device on a table
- * on a smooth train moving at constant velocity may not trigger motion.
- *
- * The only allowed value to return is 1.0.
- */
-#define SENSOR_TYPE_MOTION_DETECT                       (30)
 #define SENSOR_STRING_TYPE_MOTION_DETECT                "android.sensor.motion_detect"
-
-/*
- * SENSOR_TYPE_HEART_BEAT
- * trigger mode: continuous
- *
- * A sensor of this type returns an event everytime a hear beat peak is
- * detected.
- *
- * Peak here ideally corresponds to the positive peak in the QRS complex of
- * and ECG signal.
- *
- * The sensor is not expected to be optimized for latency. As a guide, a
- * latency of up to 10 seconds is acceptable. However the timestamp attached
- * to the event should be accurate and should correspond to the time the peak
- * occured.
- *
- * The sensor event contains a parameter for the confidence in the detection
- * of the peak where 0.0 represent no information at all, and 1.0 represents
- * certainty.
- */
-#define SENSOR_TYPE_HEART_BEAT                          (31)
 #define SENSOR_STRING_TYPE_HEART_BEAT                   "android.sensor.heart_beat"
-
-/**
- * SENSOR_TYPE_DYNAMIC_SENSOR_META
- * trigger-mode: special
- *
- * A sensor event of this type is received when a dynamic sensor is added to or removed from the
- * system. At most one sensor of this type can be present in one sensor HAL implementation and
- * presence of a sensor of this type in sensor HAL implementation indicates that this sensor HAL
- * supports dynamic sensor feature. Operations, such as batch, activate and setDelay, to this
- * special purpose sensor should be treated as no-op and return successful.
- *
- * A dynamic sensor connection indicates connection of a physical device or instantiation of a
- * virtual sensor backed by algorithm; and a dynamic sensor disconnection indicates the the
- * opposite. A sensor event of SENSOR_TYPE_DYNAMIC_SENSOR_META type should be delivered regardless
- * of the activation status of the sensor in the event of dynamic sensor connection and
- * disconnection. In the sensor event, besides the common data entries, "dynamic_sensor_meta", which
- * includes fields for connection status, handle of the sensor involved, pointer to sensor_t
- * structure and a uuid field, should be populated.
- *
- * At a dynamic sensor connection event, fields of sensor_t structure referenced by a pointer in
- * dynamic_sensor_meta should be filled as if it was regular sensors. Sensor HAL is responsible for
- * recovery of memory if the corresponding data is dynamicially allocated. However, the the pointer
- * must be valid until the first activate call to the sensor reported in this connection event. At a
- * dynamic sensor disconnection, the sensor_t pointer should be NULL.
- *
- * The sensor handle assigned to dynamic sensors should never be the same as that of any regular
- * static sensors, and should be unique until next boot. In another word, if a handle h is used for
- * a dynamic sensor A, that same number cannot be used for the same dynamic sensor A or another
- * dynamic sensor B even after disconnection of A until reboot.
- *
- * The UUID field will be used for identifying the sensor in addition to name, vendor and version
- * and type. For physical sensors of the same model, all sensors will have the same values in
- * sensor_t, but the UUID should be unique and persistent for each individual unit. An all zero UUID
- * indicates it is not possible to differentiate individual sensor unit.
- *
- */
-#define SENSOR_TYPE_DYNAMIC_SENSOR_META                         (32)
-#define SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META                  "android.sensor.dynamic_sensor_meta"
-
-/**
- * SENSOR_TYPE_ADDITIONAL_INFO
- * reporting-mode: N/A
- *
- * This sensor type is for delivering additional sensor information aside from sensor event data.
- * Additional information may include sensor front-end group delay, internal calibration parameters,
- * noise level metrics, device internal temperature, etc.
- *
- * This type will never bind to a sensor. In other words, no sensor in the sensor list should be of
- * the type SENSOR_TYPE_ADDITIONAL_INFO. If a sensor HAL supports sensor additional information
- * feature, it reports sensor_event_t with "sensor" field set to handle of the reporting sensor and
- * "type" field set to SENSOR_TYPE_ADDITIONAL_INFO. Delivery of additional information events is
- * triggered under two conditions: an enable activate() call or a flush() call to the corresponding
- * sensor.
- *
- * A single additional information report consists of multiple frames. Sequences of these frames are
- * ordered using timestamps, which means the timestamps of sequential frames have to be at least 1
- * nanosecond apart from each other. Each frame is a sensor_event_t delivered through the HAL
- * interface, with related data stored in the "additional_info" field, which is of type
- * additional_info_event_t.  The "type" field of additional_info_event_t denotes the nature of the
- * payload data (see additional_info_type_t).  The "serial" field is used to keep the sequence of
- * payload data that spans multiple frames. The first frame of the entire report is always of type
- * AINFO_BEGIN, and the last frame is always AINFO_END.
- *
- * All additional information frames have to be delivered after flush complete event if flush() was
- * triggering the report.
- */
-#define SENSOR_TYPE_ADDITIONAL_INFO                       (33)
-#define SENSOR_STRING_TYPE_ADDITIONAL_INFO                "android.sensor.additional_info"
+#define SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META          "android.sensor.dynamic_sensor_meta"
+#define SENSOR_STRING_TYPE_ADDITIONAL_INFO              "android.sensor.additional_info"
+#define SENSOR_STRING_TYPE_LOW_LATENCY_OFFBODY_DETECT   "android.sensor.low_latency_offbody_detect"
+#define SENSOR_STRING_TYPE_ACCELEROMETER_UNCALIBRATED   "android.sensor.accelerometer_uncalibrated"
 
 /**
  * Values returned by the accelerometer in various locations in the universe.
@@ -876,16 +199,6 @@
 /** Minimum magnetic field on Earth's surface */
 #define MAGNETIC_FIELD_EARTH_MIN    (30.0f)
 
-/**
- * Possible values of the status field of sensor events.
- */
-#define SENSOR_STATUS_NO_CONTACT        -1
-#define SENSOR_STATUS_UNRELIABLE        0
-#define SENSOR_STATUS_ACCURACY_LOW      1
-#define SENSOR_STATUS_ACCURACY_MEDIUM   2
-#define SENSOR_STATUS_ACCURACY_HIGH     3
-
-
 struct sensor_t;
 
 /**
@@ -910,7 +223,7 @@
 } sensors_vec_t;
 
 /**
- * uncalibrated gyroscope and magnetometer event data
+ * uncalibrated accelerometer, gyroscope and magnetometer event data
  */
 typedef struct {
   union {
@@ -977,75 +290,6 @@
     };
 } additional_info_event_t;
 
-typedef enum additional_info_type {
-    //
-    AINFO_BEGIN = 0x0,                      // Marks the beginning of additional information frames
-    AINFO_END   = 0x1,                      // Marks the end of additional information frames
-    // Basic information
-    AINFO_UNTRACKED_DELAY =  0x10000,       // Estimation of the delay that is not tracked by sensor
-                                            // timestamps. This includes delay introduced by
-                                            // sensor front-end filtering, data transport, etc.
-                                            // float[2]: delay in seconds
-                                            //           standard deviation of estimated value
-                                            //
-    AINFO_INTERNAL_TEMPERATURE,             // float: Celsius temperature.
-                                            //
-    AINFO_VEC3_CALIBRATION,                 // First three rows of a homogeneous matrix, which
-                                            // represents calibration to a three-element vector
-                                            // raw sensor reading.
-                                            // float[12]: 3x4 matrix in row major order
-                                            //
-    AINFO_SENSOR_PLACEMENT,                 // Location and orientation of sensor element in the
-                                            // device frame: origin is the geometric center of the
-                                            // mobile device screen surface; the axis definition
-                                            // corresponds to Android sensor definitions.
-                                            // float[12]: 3x4 matrix in row major order
-                                            //
-    AINFO_SAMPLING,                         // float[2]: raw sample period in seconds,
-                                            //           standard deviation of sampling period
-
-    // Sampling channel modeling information
-    AINFO_CHANNEL_NOISE = 0x20000,          // int32_t: noise type
-                                            // float[n]: parameters
-                                            //
-    AINFO_CHANNEL_SAMPLER,                  // float[3]: sample period
-                                            //           standard deviation of sample period,
-                                            //           quantization unit
-                                            //
-    AINFO_CHANNEL_FILTER,                   // Represents a filter:
-                                            //      \sum_j a_j y[n-j] == \sum_i b_i x[n-i]
-                                            //
-                                            // int32_t[3]: number of feedforward coefficients, M,
-                                            //             number of feedback coefficients, N, for
-                                            //               FIR filter, N=1.
-                                            //             bit mask that represents which element to
-                                            //               which the filter is applied, bit 0 == 1
-                                            //               means this filter applies to vector
-                                            //               element 0.
-                                            // float[M+N]: filter coefficients (b0, b1, ..., BM-1),
-                                            //             then (a0, a1, ..., aN-1), a0 is always 1.
-                                            //             Multiple frames may be needed for higher
-                                            //             number of taps.
-                                            //
-    AINFO_CHANNEL_LINEAR_TRANSFORM,         // int32_t[2]: size in (row, column) ... 1st frame
-                                            // float[n]: matrix element values in row major order.
-                                            //
-    AINFO_CHANNEL_NONLINEAR_MAP,            // int32_t[2]: extrapolate method
-                                            //             interpolate method
-                                            // float[n]: mapping key points in pairs, (in, out)...
-                                            //           (may be used to model saturation)
-                                            //
-    AINFO_CHANNEL_RESAMPLER,                // int32_t:  resample method (0-th order, 1st order...)
-                                            // float[1]: resample ratio (upsampling if < 1.0;
-                                            //           downsampling if > 1.0).
-                                            //
-
-    // Custom information
-    AINFO_CUSTOM_START =    0x10000000,     //
-    // Debugging
-    AINFO_DEBUGGING_START = 0x40000000,     //
-} additional_info_type_t;
-
 /**
  * Union of the various types of sensor data
  * that can be returned.
@@ -1103,6 +347,9 @@
             /* uncalibrated magnetometer values are in micro-Teslas */
             uncalibrated_event_t uncalibrated_magnetic;
 
+            /* uncalibrated accelerometer values are in  meter per second per second (m/s^2) */
+            uncalibrated_event_t uncalibrated_accelerometer;
+
             /* heart rate data containing value in bpm and status */
             heart_rate_event_t heart_rate;
 
@@ -1151,7 +398,7 @@
 
     /**
      * Enumerate all available sensors. The list is returned in "list".
-     * @return number of sensors in the list
+     * return number of sensors in the list
      */
     int (*get_sensors_list)(struct sensors_module_t* module,
             struct sensor_t const** list);
@@ -1162,7 +409,7 @@
      *  0 - Normal operation. Default state of the module.
      *  1 - Loopback mode. Data is injected for the supported
      *      sensors by the sensor service in this mode.
-     * @return 0 on success
+     * return 0 on success
      *         -EINVAL if requested mode is not supported
      *         -EPERM if operation is not allowed
      */
@@ -1225,13 +472,14 @@
      */
     uint32_t        fifoMaxEventCount;
 
-    /* type of this sensor as a string. Set to corresponding
-     * SENSOR_STRING_TYPE_*.
-     * When defining an OEM specific sensor or sensor manufacturer specific
-     * sensor, use your reserve domain name as a prefix.
-     * ex: com.google.glass.onheaddetector
-     * For sensors of known type, the android framework might overwrite this
-     * string automatically.
+    /* type of this sensor as a string.
+     *
+     * If type is OEM specific or sensor manufacturer specific type
+     * (>=SENSOR_TYPE_DEVICE_PRIVATE_BASE), this string must be defined with reserved domain of
+     * vendor/OEM as a prefix, e.g. com.google.glass.onheaddetector
+     *
+     * For sensors of Android defined types, Android framework will override this value. It is ok to
+     * leave it pointing to an empty string.
      */
     const char*    stringType;
 
@@ -1277,6 +525,23 @@
     void*           reserved[2];
 };
 
+/**
+ * Shared memory information for a direct channel
+ */
+struct sensors_direct_mem_t {
+    int type;                           // enum SENSOR_DIRECT_MEM_...
+    int format;                         // enum SENSOR_DIRECT_FMT_...
+    size_t size;                        // size of the memory region, in bytes
+    const struct native_handle *handle; // shared memory handle, which is interpreted differently
+                                        // depending on type
+};
+
+/**
+ * Direct channel report configuration
+ */
+struct sensors_direct_cfg_t {
+    int rate_level;             // enum SENSOR_DIRECT_RATE_...
+};
 
 /*
  * sensors_poll_device_t is used with SENSORS_DEVICE_API_VERSION_0_1
@@ -1308,11 +573,16 @@
         struct {
             struct hw_device_t common;
 
-            /* Activate/de-activate one sensor. Return 0 on success, negative
+            /* Activate/de-activate one sensor.
              *
              * sensor_handle is the handle of the sensor to change.
              * enabled set to 1 to enable, or 0 to disable the sensor.
              *
+             * After sensor de-activation, existing sensor events that have not
+             * been picked up by poll() should be abandoned immediately so that
+             * subsequent activation will not get stale sensor events (events
+             * that is generated prior to the latter activation).
+             *
              * Return 0 on success, negative errno code otherwise.
              */
             int (*activate)(struct sensors_poll_device_t *dev,
@@ -1328,7 +598,13 @@
                     int sensor_handle, int64_t sampling_period_ns);
 
             /**
-             * Returns an array of sensor data.
+             * Write an array of sensor_event_t to data. The size of the
+             * available buffer is specified by count. Returns number of
+             * valid sensor_event_t.
+             *
+             * This function should block if there is no sensor event
+             * available when being called. Thus, return value should always be
+             * positive.
              */
             int (*poll)(struct sensors_poll_device_t *dev,
                     sensors_event_t* data, int count);
@@ -1367,13 +643,67 @@
     /*
      * Inject a single sensor sample to be to this device.
      * data points to the sensor event to be injected
-     * @return 0 on success
+     * return 0 on success
      *         -EPERM if operation is not allowed
      *         -EINVAL if sensor event cannot be injected
      */
     int (*inject_sensor_data)(struct sensors_poll_device_1 *dev, const sensors_event_t *data);
 
-    void (*reserved_procs[7])(void);
+    /*
+     * Register/unregister direct report channel.
+     *
+     * A HAL declares support for direct report by setting non-NULL values for both
+     * register_direct_channel and config_direct_report.
+     *
+     * This function has two operation modes:
+     *
+     * Register: mem != NULL, register a channel using supplied shared memory information. By the
+     * time this function returns, sensors must finish initializing shared memory content
+     * (format dependent, see SENSOR_DIRECT_FMT_*).
+     *      Parameters:
+     *          mem             points to a valid struct sensors_direct_mem_t.
+     *          channel_handle  is ignored.
+     *      Return value:
+     *          A handle of channel (>0, <INT32_MAX) when success, which later can be referred in
+     *          unregister or config_direct_report call, or error code (<0) when failed
+     * Unregister: mem == NULL, unregister a previously registered channel.
+     *      Parameters:
+     *          mem             set to NULL
+     *          channel_handle  contains handle of channel to be unregistered
+     *      Return value:
+     *          0, even if the channel_handle is invalid, in which case it will be a no-op.
+     */
+    int (*register_direct_channel)(struct sensors_poll_device_1 *dev,
+            const struct sensors_direct_mem_t* mem, int channel_handle);
+
+    /*
+     * Configure direct sensor event report in direct channel.
+     *
+     * Start, modify rate or stop direct report of a sensor in a certain direct channel. A special
+     * case is setting sensor handle -1 to stop means to stop all active sensor report on the
+     * channel specified.
+     *
+     * A HAL declares support for direct report by setting non-NULL values for both
+     * register_direct_channel and config_direct_report.
+     *
+     * Parameters:
+     *      sensor_handle   sensor to be configured. The sensor has to support direct report
+     *                      mode by setting flags of sensor_t. Also, direct report mode is only
+     *                      defined for continuous reporting mode sensors.
+     *      channel_handle  channel handle to be configured.
+     *      config          direct report parameters, see sensor_direct_cfg_t.
+     * Return value:
+     *      - when sensor is started or sensor rate level is changed: return positive identifier of
+     *        sensor in specified channel if successful, otherwise return negative error code.
+     *      - when sensor is stopped: return 0 for success or negative error code for failure.
+     */
+    int (*config_direct_report)(struct sensors_poll_device_1 *dev,
+            int sensor_handle, int channel_handle, const struct sensors_direct_cfg_t *config);
+
+    /*
+     * Reserved for future use, must be zero.
+     */
+    void (*reserved_procs[5])(void);
 
 } sensors_poll_device_1_t;
 
@@ -1383,7 +713,7 @@
 static inline int sensors_open(const struct hw_module_t* module,
         struct sensors_poll_device_t** device) {
     return module->methods->open(module,
-            SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
+            SENSORS_HARDWARE_POLL, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int sensors_close(struct sensors_poll_device_t* device) {
@@ -1393,7 +723,7 @@
 static inline int sensors_open_1(const struct hw_module_t* module,
         sensors_poll_device_1_t** device) {
     return module->methods->open(module,
-            SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
+            SENSORS_HARDWARE_POLL, TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int sensors_close_1(sensors_poll_device_1_t* device) {
diff --git a/include/hardware/sound_trigger.h b/include/hardware/sound_trigger.h
index e1abbc9..d7828ac 100644
--- a/include/hardware/sound_trigger.h
+++ b/include/hardware/sound_trigger.h
@@ -124,7 +124,7 @@
                                        struct sound_trigger_hw_device** device)
 {
     return module->methods->open(module, SOUND_TRIGGER_HARDWARE_INTERFACE,
-                                 (struct hw_device_t**)device);
+                                 TO_HW_DEVICE_T_OPEN(device));
 }
 
 static inline int sound_trigger_hw_device_close(struct sound_trigger_hw_device* device)
diff --git a/include/hardware/vehicle.h b/include/hardware/vehicle.h
index a590fbd..8b28e7a 100644
--- a/include/hardware/vehicle.h
+++ b/include/hardware/vehicle.h
@@ -83,7 +83,6 @@
 
 /**
  * Invalid property value used for argument where invalid property gives different result.
- * @range_start
  */
 #define VEHICLE_PROPERTY_INVALID (0x0)
 
@@ -122,7 +121,7 @@
  * @data_member info_model_year
  * @unit VEHICLE_UNIT_TYPE_YEAR
  */
-#define VEHICLE_PROPERTY_INFO_MODEL_YEAR                           (0x00000103)
+#define VEHICLE_PROPERTY_INFO_MODEL_YEAR                            (0x00000103)
 
 /**
  * Fuel capacity of the vehicle
@@ -253,7 +252,7 @@
 
 
 
- //==== HVAC Properties ====
+//==== HVAC Properties ====
 
 /**
  * Fan speed setting
@@ -261,8 +260,7 @@
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
  * @data_member hvac.fan_speed
- * @zone_type VEHICLE_ZONE
- * @data_enum TODO
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @allow_out_of_range_value : OFF
  */
 #define VEHICLE_PROPERTY_HVAC_FAN_SPEED                             (0x00000500)
@@ -273,8 +271,8 @@
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
  * @data_member hvac.fan_direction
- * @zone_type VEHICLE_ZONE
- * @data_enum TODO
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
+ * @data_enum vehicle_hvac_fan_direction
  * @allow_out_of_range_value : OFF
  */
 #define VEHICLE_PROPERTY_HVAC_FAN_DIRECTION                         (0x00000501)
@@ -293,9 +291,9 @@
 /**
  * HVAC current temperature.
  * @value_type VEHICLE_VALUE_TYPE_ZONED_FLOAT
- * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.temperature_current
  */
 #define VEHICLE_PROPERTY_HVAC_TEMPERATURE_CURRENT                   (0x00000502)
@@ -303,9 +301,9 @@
 /**
  * HVAC, target temperature set.
  * @value_type VEHICLE_VALUE_TYPE_ZONED_FLOAT
- * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.temperature_set
  * @allow_out_of_range_value : MIN / MAX / OFF
  */
@@ -316,7 +314,7 @@
  * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
- * @zone_type VEHICLE_WINDOW
+ * @zone_type VEHICLE_ZONE_TYPE_WINDOW
  * @data_member hvac.defrost_on
  */
 #define VEHICLE_PROPERTY_HVAC_DEFROSTER                             (0x00000504)
@@ -327,7 +325,7 @@
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
  * @config_flags Supported zones
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.ac_on
  */
 #define VEHICLE_PROPERTY_HVAC_AC_ON                                 (0x00000505)
@@ -337,7 +335,7 @@
  * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.max_ac_on
  */
 #define VEHICLE_PROPERTY_HVAC_MAX_AC_ON                             (0x00000506)
@@ -347,7 +345,7 @@
  * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.max_defrost_on
  */
 #define VEHICLE_PROPERTY_HVAC_MAX_DEFROST_ON                        (0x00000507)
@@ -357,7 +355,7 @@
  * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.max_recirc_on
  */
 #define VEHICLE_PROPERTY_HVAC_RECIRC_ON                             (0x00000508)
@@ -367,12 +365,94 @@
  * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.dual_on
  */
 #define VEHICLE_PROPERTY_HVAC_DUAL_ON                               (0x00000509)
 
 /**
+ * On/off automatic mode
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
+ * @data_member hvac.auto_on
+ */
+#define VEHICLE_PROPERTY_HVAC_AUTO_ON                               (0x0000050A)
+
+/**
+ * Seat temperature
+ *
+ * Negative values indicate cooling.
+ * 0 indicates off.
+ * Positive values indicate heating.
+ *
+ * Some vehicles may have multiple levels of heating and cooling. The min/max
+ * range defines the allowable range and number of steps in each direction.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_HVAC_SEAT_TEMPERATURE                      (0x0000050B)
+
+/**
+ * Side Mirror Heat
+ *
+ * Increase values denote higher heating levels for side mirrors.
+ * 0 indicates heating is turned off.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_HVAC_SIDE_MIRROR_HEAT                      (0x0000050C)
+
+/**
+ * Steering Wheel Temperature
+ *
+ * Sets the temperature for the steering wheel
+ * Positive value indicates heating.
+ * Negative value indicates cooling.
+ * 0 indicates tempreature control is off.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_HVAC_STEERING_WHEEL_TEMP                   (0x0000050D)
+
+/**
+ * Temperature units
+ *
+ * Indicates whether the temperature is in Celsius, Fahrenheit, or a different unit.
+ * This parameter affects all HVAC temperatures in the system.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ
+ * @data_enum vehicle_unit_type
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_HVAC_TEMPERATURE_UNITS                     (0x0000050E)
+
+/**
+ * Actual fan speed
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ
+ * @data_member hvac.fan_speed
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
+ * @allow_out_of_range_value : OFF
+ */
+#define VEHICLE_PROPERTY_HVAC_ACTUAL_FAN_SPEED_RPM                  (0x0000050F)
+
+
+/**
  * Represents power state for HVAC. Some HVAC properties will require matching power to be turned on
  * to get out of OFF state. For non-zoned HVAC properties, VEHICLE_ALL_ZONE corresponds to
  * global power state.
@@ -383,12 +463,31 @@
  * @config_string list of HVAC properties whose power is controlled by this property. Format is
  *                hexa-decimal number (0x...) separated by comma like "0x500,0x503". All zones
  *                defined in these affected properties should be available in the property.
- * @zone_type VEHICLE_ZONE
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
  * @data_member hvac.power_on
  */
 #define VEHICLE_PROPERTY_HVAC_POWER_ON                              (0x00000510)
 
 /**
+ * Fan Positions Available
+ *
+ * This is a bit mask of fan positions available for the zone.  Each entry in
+ * vehicle_hvac_fan_direction is selected by bit position.  For instance, if
+ * only the FAN_DIRECTION_FACE (0x1) and FAN_DIRECTION_DEFROST (0x4) are available,
+ * then this value shall be set to 0x12.
+ *
+ * 0x12 = (1 << 1) | (1 << 4)
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC
+ * @access VEHICLE_PROP_ACCESS_READ
+ * @data_member int32_value
+ * @zone_type VEHICLE_ZONE_TYPE_ZONE
+ * @allow_out_of_range_value : OFF
+ */
+#define VEHICLE_PROPERTY_HVAC_FAN_DIRECTION_AVAILABLE               (0x00000511)
+
+/**
  * Outside temperature
  * @value_type VEHICLE_VALUE_TYPE_FLOAT
  * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS
@@ -396,8 +495,7 @@
  * @data_member outside_temperature
  * @unit VEHICLE_UNIT_TYPE_CELCIUS
  */
-
-#define VEHICLE_PROPERTY_ENV_OUTSIDE_TEMPERATURE                   (0x00000703)
+#define VEHICLE_PROPERTY_ENV_OUTSIDE_TEMPERATURE                    (0x00000703)
 
 
 /**
@@ -408,7 +506,7 @@
  * @data_member cabin_temperature
  * @unit VEHICLE_UNIT_TYPE_CELCIUS
  */
-#define VEHICLE_PROPERTY_ENV_CABIN_TEMPERATURE                  (0x00000704)
+#define VEHICLE_PROPERTY_ENV_CABIN_TEMPERATURE                      (0x00000704)
 
 
 /*
@@ -434,7 +532,7 @@
  * @config_flags Number of presets supported
  * @data_member int32_array
  */
-#define VEHICLE_PROPERTY_RADIO_PRESET                               (0x0000801)
+#define VEHICLE_PROPERTY_RADIO_PRESET                               (0x00000801)
 
 /**
  * Constants relevant to radio.
@@ -492,7 +590,13 @@
  *                       VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT when car side is playing something
  *                       permanent.
  *                   LOSS_TRANSIENT: always should be VEHICLE_AUDIO_EXT_FOCUS_CAR_TRANSIENT
- *   int32_array[3]: should be zero.
+ *   int32_array[3]: context requested by android side when responding to focus request.
+ *                   When car side is taking focus away, this should be zero.
+ *
+ * A focus response should be sent per each focus request even if there is no change in
+ * focus state. This can happen in case like focus request only involving context change
+ * where android side still needs matching focus response to confirm that audio module
+ * has made necessary changes.
  *
  * If car does not support VEHICLE_PROPERTY_AUDIO_FOCUS, focus is assumed to be granted always.
  *
@@ -501,7 +605,7 @@
  * @access VEHICLE_PROP_ACCESS_READ_WRITE
  * @data_member int32_array
  */
-#define VEHICLE_PROPERTY_AUDIO_FOCUS                                  (0x00000900)
+#define VEHICLE_PROPERTY_AUDIO_FOCUS                                (0x00000900)
 
 enum vehicle_audio_focus_request {
     VEHICLE_AUDIO_FOCUS_REQUEST_GAIN = 0x1,
@@ -638,13 +742,23 @@
     VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG               = 0x400,
     /** Radio is played */
     VEHICLE_AUDIO_CONTEXT_RADIO_FLAG                      = 0x800,
+    /** Ext source is played. This is for tagging generic ext sources. */
+    VEHICLE_AUDIO_CONTEXT_EXT_SOURCE_FLAG                 = 0x1000,
 };
 
 /**
  * Property to control audio volume of each audio context.
  *
+ * vehicle_prop_config_t
+ *   config_array[0] : bit flags of all supported audio contexts. If this is 0,
+ *                     audio volume is controlled per physical stream
+ *   config_array[1] : flags defined in vehicle_audio_volume_capability_flag to
+ *                     represent audio module's capability.
+ *
  * Data type looks like:
- *   int32_array[0] : stream context as defined in vehicle_audio_context_flag.
+ *   int32_array[0] : stream context as defined in vehicle_audio_context_flag. If only physical
+                      stream is supported (config_array[0] == 0), this will represent physical
+                      stream number.
  *   int32_array[1] : volume level, valid range is 0 to int32_max_value defined in config.
  *                    0 will be mute state. int32_min_value in config should be always 0.
  *   int32_array[2] : One of vehicle_audio_volume_state.
@@ -658,7 +772,34 @@
  * @config_flags all audio contexts supported.
  * @data_member int32_array
  */
-#define VEHICLE_PROPERTY_AUDIO_VOLUME                                 (0x00000901)
+#define VEHICLE_PROPERTY_AUDIO_VOLUME                               (0x00000901)
+
+
+/**
+ * flags to represent capability of audio volume property.
+ * used in config_array[1] of vehicle_prop_config_t.
+ */
+enum vehicle_audio_volume_capability_flag {
+    /**
+     * External audio module or vehicle hal has persistent storage
+     * to keep the volume level. This should be set only when per context
+     * volume level is supproted. When this is set, audio volume level per
+     * each context will be retrieved from the property when systen starts up.
+     * And external audio module is also expected to adjust volume automatically
+     * whenever there is an audio context change.
+     * When this flag is not set, android side will assume that there is no
+     * persistent storage and stored value in android side will be used to
+     * initialize the volume level. And android side will set volume level
+     * of each physical streams whenever there is an audio context change.
+     */
+    VEHICLE_AUDIO_VOLUME_CAPABILITY_PERSISTENT_STORAGE = 0x1,
+    /**
+     * When this flag is set, the H/W can support only single master volume for all streams.
+     * There is no way to set volume level differently per each stream or context.
+     */
+    VEHICLE_AUDIO_VOLUME_CAPABILITY_MASTER_VOLUME_ONLY = 0x2,
+};
+
 
 /**
  * enum to represent audio volume state.
@@ -683,8 +824,18 @@
 
 /**
  * Property for handling volume limit set by user. This limits maximum volume that can be set
- * per each context.
- *   int32_array[0] : stream context as defined in vehicle_audio_context_flag.
+ * per each context or physical stream.
+ *
+ * vehicle_prop_config_t
+ *   config_array[0] : bit flags of all supported audio contexts. If this is 0,
+ *                     audio volume is controlled per physical stream
+ *   config_array[1] : flags defined in vehicle_audio_volume_capability_flag to
+ *                     represent audio module's capability.
+ *
+ * Data type looks like:
+ *   int32_array[0] : stream context as defined in vehicle_audio_context_flag. If only physical
+ *                    stream is supported (config_array[0] == 0), this will represent physical
+ *                    stream number.
  *   int32_array[1] : maximum volume set to the stream. If there is no restriction, this value
  *                    will be  bigger than VEHICLE_PROPERTY_AUDIO_VOLUME's max value.
  *
@@ -698,7 +849,7 @@
  * @config_flags all audio contexts supported.
  * @data_member int32_array
  */
-#define VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT                           (0x00000902)
+#define VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT                         (0x00000902)
 
 /**
  * Index in int32_array for VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT property.
@@ -727,7 +878,7 @@
  * @access VEHICLE_PROP_ACCESS_WRITE
  * @data_member int32_array
  */
-#define VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY                         (0x00000903)
+#define VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY                       (0x00000903)
 
 /**
  * Index in int32_array for VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY property.
@@ -750,7 +901,7 @@
 *               this.
 * @data_member int32_value
 */
-#define VEHICLE_PROPERTY_AUDIO_HW_VARIANT                             (0x00000904)
+#define VEHICLE_PROPERTY_AUDIO_HW_VARIANT                           (0x00000904)
 
 /**
  * Flag to be used in vehicle_prop_config.config_flags for VEHICLE_PROPERTY_AUDIO_HW_VARIANT.
@@ -766,6 +917,70 @@
     VEHICLE_AUDIO_HW_VARIANT_FLAG_INTERNAL_RADIO_FLAG = 0x1,
 };
 
+/** audio routing for AM/FM. This should be also be the value when there is only one
+    radio module in the system. */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_AM_FM "RADIO_AM_FM"
+/** Should be added only when there is a separate radio module with HD capability. */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_AM_FM_HD "RADIO_AM_FM_HD"
+/** For digial audio broadcasting type of radio */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_DAB "RADIO_DAB"
+/** For satellite type of radio */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_SATELLITE "RADIO_SATELLITE"
+/** For CD or DVD */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_CD_DVD "CD_DVD"
+/** For 1st auxiliary input */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_AUX_IN0 "AUX_IN0"
+/** For 2nd auxiliary input */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_AUX_IN1 "AUX_IN1"
+/** For navigation guidance from outside android */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_NAV_GUIDANCE "EXT_NAV_GUIDANCE"
+/** For voice command from outside android */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_VOICE_COMMAND "EXT_VOICE_COMMAND"
+/** For voice call from outside android */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_VOICE_CALL "EXT_VOICE_CALL"
+/** For safety alert from outside android */
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_SAFETY_ALERT "EXT_SAFETY_ALERT"
+
+/**
+* Property to pass hint on external audio routing. When android side request focus
+* with VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG flag, this property will be set
+* before setting AUDIO_FOCUS property as a hint for external audio source routing.
+* Note that setting this property alone should not trigger any change.
+* Audio routing should be changed only when AUDIO_FOCUS property is set. Note that
+* this property allows passing custom value as long as it is defined in config_string.
+* This allows supporting non-standard routing options through this property.
+* It is recommended to use separate name space for custom property to prevent conflict in future
+* android releases.
+* Enabling each external routing option is done by enabling each bit flag for the routing.
+* This property can support up to 128 external routings.
+* To give full flexibility, there is no standard definition for each bit flag and
+* assigning each big flag to specific routing type is decided by config_string.
+* config_string has format of each entry separated by ','
+* and each entry has format of bitFlagPositon:typeString[:physicalStreamNumber].
+*  bitFlagPosition: represents which big flag will be set to enable this routing. 0 means
+*    LSB in int32_array[0]. 31 will be MSB in int32_array[0]. 127 will MSB in int32_array[3].
+*  typeString: string representation of external routing. Some types are already defined
+*    in VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_* and use them first before adding something
+*    custom. Applications will find each routing using this string.
+*  physicalStreamNumber: This part is optional and represents physical stream to android
+*    which will be disabled when this routing is enabled. If not specified, this routing
+*    should not affect physical streams to android.
+* As an example, let's assume a system with two physical streams, 0 for media and 1 for
+* nav guidance. And let's assume external routing option of am fm radio, external navigation
+* guidance, satellite radio, and one custom. Let's assume that radio and satellite replaces
+* physical stream 0 and external navigation replaces physical stream 1. And bit flag will be
+* assigned in the order listed above. This configuration will look like this in config_string:
+*  "0:RADIO_AM_FM:0,1:EXT_NAV_GUIDANCE:1,2:RADIO_SATELLITE:0,3:com.test.SOMETHING_CUSTOM"
+* When android requests RADIO_AM_FM, int32_array[0] will be set to 0x1.
+* When android requests RADIO_SATELLITE + EXT_NAV_GUIDANCE, int32_array[0] will be set to 0x2|0x4.
+*
+* @value_type VEHICLE_VALUE_TYPE_INT32_VEC4
+* @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+* @access VEHICLE_PROP_ACCESS_WRITE|VEHICLE_PROP_ACCESS_READ_WRITE
+* @config_string List of all avaiable external source in the system.
+* @data_member int32_array
+*/
+#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT                     (0x00000905)
 
 /**
  * Property to control power state of application processor.
@@ -788,7 +1003,7 @@
  * @config_flags Additional info on power state. Should use vehicle_ap_power_state_config_flag.
  * @data_member int32_array
  */
-#define VEHICLE_PROPERTY_AP_POWER_STATE                               (0x00000A00)
+#define VEHICLE_PROPERTY_AP_POWER_STATE                             (0x00000A00)
 
 enum vehicle_ap_power_state_config_flag {
     /**
@@ -895,7 +1110,7 @@
  * @access VEHICLE_PROP_ACCESS_READ|VEHICLE_PROP_ACCESS_READ_WRITE
  * @data_member int32
  */
-#define VEHICLE_PROPERTY_DISPLAY_BRIGHTNESS                        (0x00000A01)
+#define VEHICLE_PROPERTY_DISPLAY_BRIGHTNESS                         (0x00000A01)
 
 
 /**
@@ -999,7 +1214,7 @@
  * @config_array 0:vehicle_instument_cluster_type 1:hw type
  * @data_member int32_array
  */
-#define VEHICLE_PROPERTY_INSTRUMENT_CLUSTER_INFO                     (0x00000A20)
+#define VEHICLE_PROPERTY_INSTRUMENT_CLUSTER_INFO                    (0x00000A20)
 
 /**
  * Represents instrument cluster type available in system
@@ -1019,6 +1234,624 @@
 };
 
 /**
+ * Current date and time, encoded as Unix time.
+ * This value denotes the number of seconds that have elapsed since 1/1/1970.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_INT64
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_SET
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member int64_value
+ * @unit VEHICLE_UNIT_TYPE_SECS
+ */
+#define VEHICLE_PROPERTY_UNIX_TIME                                  (0x00000A30)
+
+/**
+ * Current time only.
+ * Some vehicles may not keep track of date.  This property only affects the current time, in
+ * seconds during the day.  Thus, the max value for this parameter is 86,400 (24 * 60 * 60)
+ *
+ * @value_type VEHICLE_VALUE_TYPE_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_SET
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member int32_value
+ * @unit VEHICLE_UNIT_TYPE_SECS
+ */
+#define VEHICLE_PROPERTY_CURRENT_TIME_IN_SECONDS                    (0x00000A31)
+
+
+//==== Car Cabin Properties ====
+/**
+ * Most Car Cabin properties have both a MOVE and POSITION parameter associated with them.
+ *
+ * The MOVE parameter will start moving the device in the indicated direction.  The magnitude
+ * indicates the relative speed.  For instance, setting the WINDOW_MOVE parameter to +1 will roll
+ * the window up.  Setting it to +2 (if available) will roll it up faster.
+ *
+ * The POSITION parameter will move the device to the desired position.  For instance, if the
+ * WINDOW_POS has a range of 0-100, then setting this parameter to 50 will open the window halfway.
+ * Depending upon the initial position, the window may move up or down to the 50% value.
+ *
+ * OEMs may choose to implement one or both of the MOVE/POSITION parameters depending upon the
+ * capability of the hardware.
+ */
+
+// Doors
+/**
+ * Door position
+ *
+ * This is an integer in case a door may be set to a particular position.  Max
+ * value indicates fully open, min value (0) indicates fully closed.
+ *
+ * Some vehicles (minivans) can open the door electronically.  Hence, the ability
+ * to write this property.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_DOOR
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_DOOR_POS                                   (0x00000B00)
+
+/**
+ * Door move
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_DOOR
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_DOOR_MOVE                                  (0x00000B01)
+
+
+/**
+ * Door lock
+ *
+ * 'true' indicates door is locked
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_DOOR
+ * @data_member boolean_value
+ */
+#define VEHICLE_PROPERTY_DOOR_LOCK                                  (0x00000B02)
+
+// Mirrors
+/**
+ * Mirror Z Position
+ *
+ * Positive value indicates tilt upwards, negative value is downwards
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_MIRROR
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_MIRROR_Z_POS                               (0x00000B40)
+
+/**
+ * Mirror Z Move
+ *
+ * Positive value indicates tilt upwards, negative value is downwards
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_MIRROR
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_MIRROR_Z_MOVE                              (0x00000B41)
+
+/**
+ * Mirror Y Position
+ *
+ * Positive value indicate tilt right, negative value is left
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_MIRROR
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_MIRROR_Y_POS                               (0x00000B42)
+
+/**
+ * Mirror Y Move
+ *
+ * Positive value indicate tilt right, negative value is left
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_MIRROR
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_MIRROR_Y_MOVE                              (0x00000B43)
+
+/**
+ * Mirror Lock
+ *
+ * True indicates mirror positions are locked and not changeable
+ *
+ * @value_type VEHICLE_VALUE_TYPE_BOOLEAN
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member boolean_value
+ */
+#define VEHICLE_PROPERTY_MIRROR_LOCK                                (0x00000B44)
+
+/**
+ * Mirror Fold
+ *
+ * True indicates mirrors are folded
+ *
+ * @value_type VEHICLE_VALUE_TYPE_BOOLEAN
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member boolean_value
+ */
+#define VEHICLE_PROPERTY_MIRROR_FOLD                                (0x00000B45)
+
+// Seats
+/**
+ * Seat memory select
+ *
+ * This parameter selects the memory preset to use to select the seat position.
+ * The minValue is always 0, and the maxValue determines the number of seat
+ * positions available.
+ *
+ * For instance, if the driver's seat has 3 memory presets, the maxValue will be 3.
+ * When the user wants to select a preset, the desired preset number (1, 2, or 3)
+ * is set.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_MEMORY_SELECT                         (0x00000B80)
+
+/**
+ * Seat memory set
+ *
+ * This setting allows the user to save the current seat position settings into
+ * the selected preset slot.  The maxValue for each seat position shall match
+ * the maxValue for VEHICLE_PROPERTY_SEAT_MEMORY_SELECT.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_MEMORY_SET                            (0x00000B81)
+
+/**
+ * Seatbelt buckled
+ *
+ * True indicates belt is buckled.
+ *
+ * Write access indicates automatic seat buckling capabilities.  There are no known cars at this
+ * time, but you never know...
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member boolean_value
+ */
+#define VEHICLE_PROPERTY_SEAT_BELT_BUCKLED                          (0x00000B82)
+
+/**
+ * Seatbelt height position
+ *
+ * Adjusts the shoulder belt anchor point.
+ * Max value indicates highest position
+ * Min value indicates lowest position
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_BELT_HEIGHT_POS                       (0x00000B83)
+
+/**
+ * Seatbelt height move
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_BELT_HEIGHT_MOVE                      (0x00000B84)
+
+/**
+ * Seat fore/aft position
+ *
+ * Sets the seat position forward (closer to steering wheel) and backwards.
+ * Max value indicates closest to wheel, min value indicates most rearward
+ * position.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_FORE_AFT_POS                          (0x00000B85)
+
+/**
+ * Seat fore/aft move
+ *
+ * Moves the seat position forward and aft.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_FORE_AFT_MOVE                         (0x00000B86)
+
+/**
+ * Seat backrest angle 1 position
+ *
+ * Backrest angle 1 is the actuator closest to the bottom of the seat.
+ * Max value indicates angling forward towards the steering wheel.
+ * Min value indicates full recline.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_1_POS                  (0x00000B87)
+
+/**
+ * Seat backrest angle 1 move
+ *
+ * Moves the backrest forward or recline.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_1_MOVE                 (0x00000B88)
+
+/**
+ * Seat backrest angle 2 position
+ *
+ * Backrest angle 2 is the next actuator up from the bottom of the seat.
+ * Max value indicates angling forward towards the steering wheel.
+ * Min value indicates full recline.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_2_POS                  (0x00000B89)
+
+/**
+ * Seat backrest angle 2 move
+ *
+ * Moves the backrest forward or recline.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_2_MOVE                 (0x00000B8A)
+
+/**
+ * Seat height position
+ *
+ * Sets the seat height.
+ * Max value indicates highest position.
+ * Min value indicates lowest position.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEIGHT_POS                            (0x00000B8B)
+
+/**
+ * Seat height move
+ *
+ * Moves the seat height.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEIGHT_MOVE                           (0x00000B8C)
+
+/**
+ * Seat depth position
+ *
+ * Sets the seat depth, distance from back rest to front edge of seat.
+ * Max value indicates longest depth position.
+ * Min value indicates shortest position.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_DEPTH_POS                             (0x00000B8D)
+
+/**
+ * Seat depth move
+ *
+ * Adjusts the seat depth.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_DEPTH_MOVE                            (0x00000B8E)
+
+/**
+ * Seat tilt position
+ *
+ * Sets the seat tilt.
+ * Max value indicates front edge of seat higher than back edge.
+ * Min value indicates front edge of seat lower than back edge.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_TILT_POS                              (0x00000B8F)
+
+/**
+ * Seat tilt move
+ *
+ * Tilts the seat.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_TILT_MOVE                             (0x00000B90)
+
+/**
+ * Lumber fore/aft position
+ *
+ * Pushes the lumbar support forward and backwards
+ * Max value indicates most forward position.
+ * Min value indicates most rearward position.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_LUMBAR_FORE_AFT_POS                   (0x00000B91)
+
+/**
+ * Lumbar fore/aft move
+ *
+ * Adjusts the lumbar support.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_LUMBAR_FORE_AFT_MOVE                  (0x00000B92)
+
+/**
+ * Lumbar side support position
+ *
+ * Sets the amount of lateral lumbar support.
+ * Max value indicates widest lumbar setting (i.e. least support)
+ * Min value indicates thinnest lumbar setting.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_LUMBAR_SIDE_SUPPORT_POS               (0x00000B93)
+
+/**
+ * Lumbar side support move
+ *
+ * Adjusts the amount of lateral lumbar support.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_LUMBAR_SIDE_SUPPORT_MOVE              (0x00000B94)
+
+/**
+ * Headrest height position
+ *
+ * Sets the headrest height.
+ * Max value indicates tallest setting.
+ * Min value indicates shortest setting.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEADREST_HEIGHT_POS                   (0x00000B95)
+
+/**
+ * Headrest height move
+ *
+ * Moves the headrest up and down.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEADREST_HEIGHT_MOVE                  (0x00000B96)
+
+/**
+ * Headrest angle position
+ *
+ * Sets the angle of the headrest.
+ * Max value indicates most upright angle.
+ * Min value indicates shallowest headrest angle.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEADREST_ANGLE_POS                    (0x00000B97)
+
+/**
+ * Headrest angle move
+ *
+ * Adjusts the angle of the headrest
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEADREST_ANGLE_MOVE                   (0x00000B98)
+
+/**
+ * Headrest fore/aft position
+ *
+ * Adjusts the headrest forwards and backwards.
+ * Max value indicates position closest to front of car.
+ * Min value indicates position closest to rear of car.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEADREST_FORE_AFT_POS                 (0x00000B99)
+
+/**
+ * Headrest fore/aft move
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @zone_type VEHICLE_ZONE_TYPE_SEAT
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_SEAT_HEADREST_FORE_AFT_MOVE                (0x00000B9A)
+
+
+// Windows
+/**
+ * Window Position
+ *
+ * Max = window up / closed
+ * Min = window down / open
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_WINDOW_POS                                 (0x00000BC0)
+
+/**
+ * Window Move
+ *
+ * Max = window up / closed
+ * Min = window down / open
+ * Magnitude denotes relative speed.  I.e. +2 is faster than +1 in raising the window.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_WINDOW_MOVE                                (0x00000BC1)
+
+/**
+ * Window Vent Position
+ *
+ * This feature is used to control the vent feature on a sunroof.
+ *
+ * Max = vent open
+ * Min = vent closed
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_WINDOW_VENT_POS                            (0x00000BC2)
+
+/**
+ * Window Vent Move
+ *
+ * This feature is used to control the vent feature on a sunroof.
+ *
+ * Max = vent open
+ * Min = vent closed
+ *
+ * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE
+ * @data_member int32_value
+ */
+#define VEHICLE_PROPERTY_WINDOW_VENT_MOVE                           (0x00000BC3)
+
+/**
+ * Window Lock
+ *
+ * True indicates windows are locked and can't be moved.
+ *
+ * @value_type VEHICLE_VALUE_TYPE_BOOLEAN
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
+ * @data_member boolean_value
+ */
+#define VEHICLE_PROPERTY_WINDOW_LOCK                                (0x00000BC4)
+
+
+
+/**
  *  H/W specific, non-standard property can be added as necessary. Such property should use
  *  property number in range of [VEHICLE_PROPERTY_CUSTOM_START, VEHICLE_PROPERTY_CUSTOM_END].
  *  Definition of property in this range is completely up to each HAL implementation.
@@ -1027,20 +1860,20 @@
  *  include config_string of "com.XYZ.some_further_details".
  *  @range_start
  */
-#define VEHICLE_PROPERTY_CUSTOM_START                       (0x70000000)
+#define VEHICLE_PROPERTY_CUSTOM_START                               (0x70000000)
 /** @range_end */
-#define VEHICLE_PROPERTY_CUSTOM_END                         (0x73ffffff)
+#define VEHICLE_PROPERTY_CUSTOM_END                                 (0x73ffffff)
 
 /**
  * Property range allocated for system's internal usage like testing. HAL should never declare
  * property in this range.
  * @range_start
  */
-#define VEHICLE_PROPERTY_INTERNAL_START                     (0x74000000)
+#define VEHICLE_PROPERTY_INTERNAL_START                             (0x74000000)
 /**
  * @range_end
  */
-#define VEHICLE_PROPERTY_INTERNAL_END                       (0x74ffffff)
+#define VEHICLE_PROPERTY_INTERNAL_END                               (0x74ffffff)
 
 /**
  * Value types for various properties.
@@ -1086,12 +1919,14 @@
     VEHICLE_UNIT_TYPE_METER                 = 0x00000021,
     VEHICLE_UNIT_TYPE_KILOMETER             = 0x00000023,
     // temperature
-    VEHICLE_UNIT_TYPE_CELCIUS               = 0x00000030,
+    VEHICLE_UNIT_TYPE_CELSIUS               = 0x00000030,
+    VEHICLE_UNIT_TYPE_FAHRENHEIT            = 0x00000031,
+    VEHICLE_UNIT_TYPE_KELVIN                = 0x00000032,
     // volume
     VEHICLE_UNIT_TYPE_MILLILITER            = 0x00000040,
     // time
     VEHICLE_UNIT_TYPE_NANO_SECS             = 0x00000050,
-    VEHICLE_UNOT_TYPE_SECS                  = 0x00000053,
+    VEHICLE_UNIT_TYPE_SECS                  = 0x00000053,
     VEHICLE_UNIT_TYPE_YEAR                  = 0x00000059,
 };
 
@@ -1105,8 +1940,12 @@
      */
     VEHICLE_PROP_CHANGE_MODE_STATIC         = 0x00,
     /**
-     * Property of this type will be reported when there is a change. get should return the
-     * current value.
+     * Property of this type will be reported when there is a change.
+     * get call should return the current value.
+     * Set operation for this property is assumed to be asynchronous. When the property is read
+     * (get) after set, it may still return old value until underlying H/W backing this property
+     * has actually changed the state. Once state is changed, the property will dispatch changed
+     * value as event.
      */
     VEHICLE_PROP_CHANGE_MODE_ON_CHANGE      = 0x01,
     /**
@@ -1114,6 +1953,18 @@
      * the data.
      */
     VEHICLE_PROP_CHANGE_MODE_CONTINUOUS     = 0x02,
+    /**
+     * Property of this type may be polled to get the current value.
+     */
+    VEHICLE_PROP_CHANGE_MODE_POLL           = 0x03,
+    /**
+     * This is for property where change event should be sent only when the value is
+     * set from external component. Normal value change will not trigger event.
+     * For example, clock property can send change event only when it is set, outside android,
+     * for case like user setting time or time getting update. There is no need to send it
+     * per every value change.
+     */
+    VEHICLE_PROP_CHANGE_MODE_ON_SET         = 0x04,
 };
 
 /**
@@ -1238,17 +2089,15 @@
  * Various Seats in the car.
  */
 enum vehicle_seat {
-    VEHICLE_SEAT_DRIVER_LHD             = 0x0001,
-    VEHICLE_SEAT_DRIVER_RHD             = 0x0002,
-    VEHICLE_SEAT_ROW_1_PASSENGER_LEFT   = 0x0010,
-    VEHICLE_SEAT_ROW_1_PASSENGER_CENTER = 0x0020,
-    VEHICLE_SEAT_ROW_1_PASSENGER_RIGHT  = 0x0040,
-    VEHICLE_SEAT_ROW_2_PASSENGER_LEFT   = 0x0100,
-    VEHICLE_SEAT_ROW_2_PASSENGER_CENTER = 0x0200,
-    VEHICLE_SEAT_ROW_2_PASSENGER_RIGHT  = 0x0400,
-    VEHICLE_SEAT_ROW_3_PASSENGER_LEFT   = 0x1000,
-    VEHICLE_SEAT_ROW_3_PASSENGER_CENTER = 0x2000,
-    VEHICLE_SEAT_ROW_3_PASSENGER_RIGHT  = 0x4000
+    VEHICLE_SEAT_ROW_1_LEFT   = 0x0001,
+    VEHICLE_SEAT_ROW_1_CENTER = 0x0002,
+    VEHICLE_SEAT_ROW_1_RIGHT  = 0x0004,
+    VEHICLE_SEAT_ROW_2_LEFT   = 0x0010,
+    VEHICLE_SEAT_ROW_2_CENTER = 0x0020,
+    VEHICLE_SEAT_ROW_2_RIGHT  = 0x0040,
+    VEHICLE_SEAT_ROW_3_LEFT   = 0x0100,
+    VEHICLE_SEAT_ROW_3_CENTER = 0x0200,
+    VEHICLE_SEAT_ROW_3_RIGHT  = 0x0400
 };
 
 /**
@@ -1282,6 +2131,7 @@
     VEHICLE_MIRROR_DRIVER_RIGHT  = 0x00000002,
     VEHICLE_MIRROR_DRIVER_CENTER = 0x00000004,
 };
+
 enum vehicle_turn_signal {
     VEHICLE_SIGNAL_NONE         = 0x00,
     VEHICLE_SIGNAL_RIGHT        = 0x01,
@@ -1289,6 +2139,15 @@
     VEHICLE_SIGNAL_EMERGENCY    = 0x04
 };
 
+enum vehicle_zone_type {
+    VEHICLE_ZONE_TYPE_NONE      = 0x00,
+    VEHICLE_ZONE_TYPE_ZONE    = 0x01,
+    VEHICLE_ZONE_TYPE_SEAT      = 0x02,
+    VEHICLE_ZONE_TYPE_DOOR      = 0x04,
+    VEHICLE_ZONE_TYPE_WINDOW    = 0x10,
+    VEHICLE_ZONE_TYPE_MIRROR    = 0x20,
+};
+
 /*
  * Boolean type.
  */
@@ -1468,6 +2327,7 @@
         vehicle_boolean_t max_defrost_on;
         vehicle_boolean_t recirc_on;
         vehicle_boolean_t dual_on;
+        vehicle_boolean_t auto_on;
         vehicle_boolean_t power_on;
 
         float temperature_current;
diff --git a/include/hardware/vehicle_camera.h b/include/hardware/vehicle_camera.h
deleted file mode 100644
index 8075aee..0000000
--- a/include/hardware/vehicle_camera.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_VEHICLE_CAMERA_INTERFACE_H
-#define ANDROID_VEHICLE_CAMERA_INTERFACE_H
-
-#include <errno.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#include <hardware/hardware.h>
-#include <cutils/native_handle.h>
-#include <system/window.h>
-
-__BEGIN_DECLS
-
-/*****************************************************************************/
-
-#define VEHICLE_CAMERA_HEADER_VERSION          1
-#define VEHICLE_CAMERA_MODULE_API_VERSION_1_0  HARDWARE_MODULE_API_VERSION(1, 0)
-#define VEHICLE_CAMERA_DEVICE_API_VERSION_1_0  HARDWARE_DEVICE_API_VERSION_2(1, 0, VEHICLE_CAMERA_HEADER_VERSION)
-
-/**
- * Vehicle Camera to provide interfaces for controlling cameras
- */
-
-/**
- * The id of this module
- */
-#define VEHICLE_CAMERA_HARDWARE_MODULE_ID  "vehicle_camera"
-
-/**
- *  Name of the vehicle device to open.  Extend this list as
- *  more cameras are added.  Each camera defined in vehicle_camera_type_t
- *  shall have a string defined for it.
- */
-#define VEHICLE_CAMERA_RVC_DEVICE       "vehicle_camera_rvc_device"
-
-/**
- * Each camera on the car shall be enumerated
- */
-typedef enum {
-    VEHICLE_CAMERA_RVC = 1,
-} vehicle_camera_type_t;
-
-/**
- * Describes the current state of camera device
- */
-typedef struct {
-    uint32_t overlay_on;
-    uint32_t camera_on;
-} vehicle_camera_state_t;
-
-/**
- * Bitmask of features supported by a camera module
- */
-enum {
-    VEHICLE_CAMERA_CONFIG_FLAG_ANDROID_OVERLAY_SUPPORT      = 0x1,
-    VEHICLE_CAMERA_CONFIG_FLAG_CAMERA_CROP_SUPPORT          = 0x2,
-    VEHICLE_CAMERA_CONFIG_FLAG_CAMERA_POSITIONING_SUPPORT   = 0x4
-} vehicle_camera_config_flag;
-
-typedef struct {
-    uint32_t capabilites_flags;
-    uint32_t camera_width;
-    uint32_t camera_height;
-    uint32_t display_width;
-    uint32_t display_height;
-} vehicle_camera_cap_t;
-
-/************************************************************************************/
-
-/**
- * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
- * and the fields of this data structure must begin with hw_module_t
- * followed by module specific information.
- */
-typedef struct {
-    struct hw_module_t common;
-    /**
-     * Queries the HW for the cameras installed on the vehicle
-     * @param num_cameras - number of camera devices available.  If
-     *                    0 is returned, an error has occurred and
-     *                    the return pointer shall be NULL.
-     * @return pointer to an array of vehicle_camera_type_t to
-     *         denote which cameras are installed.  This pointer is
-     *         only valid while the vehicle hal is loaded.  If the
-     *         pointer is NULL, then an error has occurred and
-     *         num_cameras shall be 0.
-     */
-    const uint32_t * (*get_camera_device_list)(uint32_t *num_cameras);
-} vehicle_camera_module_t;
-
-
-typedef struct vehicle_camera_device_t {
-    struct hw_device_t common;
-
-    const uint32_t camera_type;
-
-    /**
-     * Returns the capabilities of this camera.
-     * @param device - device handle
-     * @param cap - pointer to capabilities flags being returned
-     * @return 0 on success
-     *          -EPERM if device is invalid or not initialized
-     */
-    int (*get_capabilities)(struct vehicle_camera_device_t *device, vehicle_camera_cap_t *cap);
-
-    /**
-     * Gets the current camera crop settings.
-     * @param device - device handle
-     * @param rect - current camera crop settings
-     * @return 0 on success
-     *          -EPERM if device is not initialized
-     *          -errno on error
-     */
-    int (*get_camera_crop)(struct vehicle_camera_device_t *device, android_native_rect_t *rect);
-
-    /**
-     * Sets the camera crop.
-     * @param device - device handle
-     * @param rect - area of camera input to crop.  Must fit within
-     *             camera width and height from camera capabilities.
-     * @return 0 on success
-     *          -EPERM if device is not initialized
-     *          -errno on error
-     */
-    int (*set_camera_crop)(struct vehicle_camera_device_t *device, const android_native_rect_t *rect);
-
-    /**
-     * Gets position of the camera on the display.
-     * @param device - device handle
-     * @param rect - area of display the camera will appear when on
-     * @return 0 on success
-     *          -EPERM if device is not initialized
-     *          -errno on error
-     */
-    int (*get_camera_position)(struct vehicle_camera_device_t *device, android_native_rect_t *rect);
-
-    /**
-     * Sets position of the camera on the display.
-     * @param device - device handle
-     * @param rect - area of display the camera will appear when on.
-     *             Must fit within display width and height from
-     *             camera capabilities.
-     * @return 0 on success
-     *          -EPERM if device is not initialized
-     *          -errno on error
-     */
-    int (*set_camera_position)(struct vehicle_camera_device_t *device, const android_native_rect_t *rect);
-
-    /**
-     * Gets the current camera state.
-     * @param device - device handle
-     * @param state - last setting for the camera
-     * @return 0 on success
-     *          -EPERM if device is not initialized
-     */
-    int (*get_camera_state)(struct vehicle_camera_device_t *device, vehicle_camera_state_t *state);
-
-    /**
-     * Sets the camera state.
-     * @param device - device handle
-     * @param state - desired setting for the camera
-     * @return 0 on success
-     *          -EPERM if device is not initialized
-     *          -errno on error
-     */
-    int (*set_camera_state)(struct vehicle_camera_device_t *device, const vehicle_camera_state_t *state);
-} vehicle_camera_device_t;
-
-__END_DECLS
-
-#endif  // ANDROID_VEHICLE_CAMERA_INTERFACE_H
diff --git a/include/hardware/vibrator.h b/include/hardware/vibrator.h
index 200adf0..361085f 100644
--- a/include/hardware/vibrator.h
+++ b/include/hardware/vibrator.h
@@ -65,7 +65,7 @@
 
 static inline int vibrator_open(const struct hw_module_t* module, vibrator_device_t** device)
 {
-    return module->methods->open(module, VIBRATOR_DEVICE_ID_MAIN, (struct hw_device_t**)device);
+    return module->methods->open(module, VIBRATOR_DEVICE_ID_MAIN, TO_HW_DEVICE_T_OPEN(device));
 }
 
 __END_DECLS
diff --git a/modules/Android.mk b/modules/Android.mk
index 3bd0943..462081d 100644
--- a/modules/Android.mk
+++ b/modules/Android.mk
@@ -1,4 +1,14 @@
-hardware_modules := gralloc hwcomposer audio nfc nfc-nci local_time \
-	power usbaudio audio_remote_submix camera usbcamera consumerir sensors vibrator \
-	tv_input fingerprint input vehicle thermal vr
+hardware_modules := \
+    audio_remote_submix \
+    camera \
+    gralloc \
+    hwcomposer \
+    input \
+    radio \
+    sensors \
+    thermal \
+    usbaudio \
+    usbcamera \
+    vehicle \
+    vr
 include $(call all-named-subdir-makefiles,$(hardware_modules))
diff --git a/modules/README.android b/modules/README.android
index 57abb72..7ffc0f4 100644
--- a/modules/README.android
+++ b/modules/README.android
@@ -4,13 +4,13 @@
 libhardware.so eventually should contain *just* the HAL hub
 (hardware.c), everything in it should be rewritten as modules.
 
-Modules are .so in /system/libs/hw/ and have a well defined naming
+Modules are .so in /vendor/lib/hw/ and have a well defined naming
 convention:
 
-    /system/libs/hw/<*_HARDWARE_MODULE_ID>.<ro.product.board>.so
-    /system/libs/hw/<*_HARDWARE_MODULE_ID>.<ro.board.platform>.so
-    /system/libs/hw/<*_HARDWARE_MODULE_ID>.<ro.arch>.so
-    /system/libs/hw/<*_HARDWARE_MODULE_ID>.default.so
+    /vendor/lib/hw/<*_HARDWARE_MODULE_ID>.<ro.product.board>.so
+    /vendor/lib/hw/<*_HARDWARE_MODULE_ID>.<ro.board.platform>.so
+    /vendor/lib/hw/<*_HARDWARE_MODULE_ID>.<ro.arch>.so
+    /vendor/lib/hw/<*_HARDWARE_MODULE_ID>.default.so
 
 They also have a well defined interface which lives in include/hardware/.
 
diff --git a/modules/audio/Android.bp b/modules/audio/Android.bp
new file mode 100644
index 0000000..84daead
--- /dev/null
+++ b/modules/audio/Android.bp
@@ -0,0 +1,60 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// The default audio HAL module, which is a stub, that is loaded if no other
+// device specific modules are present. The exact load order can be seen in
+// libhardware/hardware.c
+//
+// The format of the name is audio.<type>.<hardware/etc>.so where the only
+// required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc.
+cc_library_shared {
+    name: "audio.primary.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["audio_hw.c"],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"],
+}
+
+// The stub audio HAL module, identical to the default audio hal, but with
+// different name to be loaded concurrently with other audio HALs if necessary.
+// This can also be used as skeleton for new implementations
+//
+// The format of the name is audio.<type>.<hardware/etc>.so where the only
+// required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc.
+cc_library_shared {
+    name: "audio.stub.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["audio_hw.c"],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"],
+}
+
+// The stub audio policy HAL module that can be used as a skeleton for
+// new implementations.
+cc_library_shared {
+    name: "audio_policy.stub",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["audio_policy.c"],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"],
+}
diff --git a/modules/audio/Android.mk b/modules/audio/Android.mk
deleted file mode 100644
index ef4b8f5..0000000
--- a/modules/audio/Android.mk
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# The default audio HAL module, which is a stub, that is loaded if no other
-# device specific modules are present. The exact load order can be seen in
-# libhardware/hardware.c
-#
-# The format of the name is audio.<type>.<hardware/etc>.so where the only
-# required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := audio.primary.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := audio_hw.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wno-unused-parameter
-
-include $(BUILD_SHARED_LIBRARY)
-
-# The stub audio HAL module, identical to the default audio hal, but with
-# different name to be loaded concurrently with other audio HALs if necessary.
-# This can also be used as skeleton for new implementations
-#
-# The format of the name is audio.<type>.<hardware/etc>.so where the only
-# required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := audio.stub.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := audio_hw.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wno-unused-parameter
-
-include $(BUILD_SHARED_LIBRARY)
-
-# The stub audio policy HAL module that can be used as a skeleton for
-# new implementations.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := audio_policy.stub
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := audio_policy.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wno-unused-parameter
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/audio/audio_hw.c b/modules/audio/audio_hw.c
index 68b0d3a..43d13a9 100644
--- a/modules/audio/audio_hw.c
+++ b/modules/audio/audio_hw.c
@@ -23,7 +23,7 @@
 #include <stdint.h>
 #include <sys/time.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 #include <hardware/hardware.h>
 #include <system/audio.h>
@@ -119,7 +119,7 @@
 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
                          size_t bytes)
 {
-    ALOGV("out_write: bytes: %d", bytes);
+    ALOGV("out_write: bytes: %zu", bytes);
 
     /* XXX: fake timing for audio output */
     struct stub_stream_out *out = (struct stub_stream_out *)stream;
@@ -242,7 +242,7 @@
 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
                        size_t bytes)
 {
-    ALOGV("in_read: bytes %d", bytes);
+    ALOGV("in_read: bytes %zu", bytes);
 
     /* XXX: fake timing for audio input */
     struct stub_stream_in *in = (struct stub_stream_in *)stream;
@@ -297,11 +297,9 @@
 {
     ALOGV("adev_open_output_stream...");
 
-    struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
-    struct stub_stream_out *out;
-    int ret;
-
-    out = (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
+    *stream_out = NULL;
+    struct stub_stream_out *out =
+            (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
     if (!out)
         return -ENOMEM;
 
@@ -325,11 +323,6 @@
 
     *stream_out = &out->stream;
     return 0;
-
-err_open:
-    free(out);
-    *stream_out = NULL;
-    return ret;
 }
 
 static void adev_close_output_stream(struct audio_hw_device *dev,
@@ -424,11 +417,8 @@
 {
     ALOGV("adev_open_input_stream...");
 
-    struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
-    struct stub_stream_in *in;
-    int ret;
-
-    in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
+    *stream_in = NULL;
+    struct stub_stream_in *in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
     if (!in)
         return -ENOMEM;
 
@@ -450,11 +440,6 @@
 
     *stream_in = &in->stream;
     return 0;
-
-err_open:
-    free(in);
-    *stream_in = NULL;
-    return ret;
 }
 
 static void adev_close_input_stream(struct audio_hw_device *dev,
@@ -483,7 +468,6 @@
     ALOGV("adev_open: %s", name);
 
     struct stub_audio_device *adev;
-    int ret;
 
     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
         return -EINVAL;
diff --git a/modules/audio/audio_policy.c b/modules/audio/audio_policy.c
index 9335654..4f9cd5a 100644
--- a/modules/audio/audio_policy.c
+++ b/modules/audio/audio_policy.c
@@ -241,9 +241,7 @@
                              void *service,
                              struct audio_policy **ap)
 {
-    struct default_ap_device *dev;
     struct default_audio_policy *dap;
-    int ret;
 
     *ap = NULL;
 
diff --git a/modules/audio_remote_submix/Android.mk b/modules/audio_remote_submix/Android.mk
index 90da396..c9e851f 100644
--- a/modules/audio_remote_submix/Android.mk
+++ b/modules/audio_remote_submix/Android.mk
@@ -18,11 +18,13 @@
 
 LOCAL_MODULE := audio.r_submix.default
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SRC_FILES := \
 	audio_hw.cpp
 LOCAL_C_INCLUDES += \
 	frameworks/av/include/ \
-	frameworks/native/include/
+	frameworks/native/include/ \
+	$(call include-path-for, audio-utils)
 LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libnbaio
 LOCAL_STATIC_LIBRARIES := libmedia_helper
 LOCAL_MODULE_TAGS := optional
diff --git a/modules/vibrator/Android.mk b/modules/camera/3_0/Android.mk
similarity index 66%
rename from modules/vibrator/Android.mk
rename to modules/camera/3_0/Android.mk
index b6b480c..ae68ed5 100644
--- a/modules/vibrator/Android.mk
+++ b/modules/camera/3_0/Android.mk
@@ -16,15 +16,30 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := vibrator.default
-
-# HAL module implementation stored in
-# hw/<VIBRATOR_HARDWARE_MODULE_ID>.default.so
+LOCAL_MODULE := camera.default
 LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_C_INCLUDES := hardware/libhardware
-LOCAL_SRC_FILES := vibrator.c
-LOCAL_SHARED_LIBRARIES := liblog
+
+LOCAL_C_INCLUDES += \
+	system/core/include \
+	system/media/camera/include \
+
+LOCAL_SRC_FILES := \
+	CameraHAL.cpp \
+	Camera.cpp \
+	ExampleCamera.cpp \
+	Metadata.cpp \
+	Stream.cpp \
+	VendorTags.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+	libcamera_metadata \
+	libcutils \
+	liblog \
+	libsync \
+	libutils \
+
+LOCAL_CFLAGS += -Wall -Wextra -fvisibility=hidden
+
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
-
diff --git a/modules/camera/Camera.cpp b/modules/camera/3_0/Camera.cpp
similarity index 100%
rename from modules/camera/Camera.cpp
rename to modules/camera/3_0/Camera.cpp
diff --git a/modules/camera/Camera.h b/modules/camera/3_0/Camera.h
similarity index 99%
rename from modules/camera/Camera.h
rename to modules/camera/3_0/Camera.h
index 0ceaf25..072de35 100644
--- a/modules/camera/Camera.h
+++ b/modules/camera/3_0/Camera.h
@@ -34,7 +34,7 @@
     public:
         // id is used to distinguish cameras. 0 <= id < NUM_CAMERAS.
         // module is a handle to the HAL module, used when the device is opened.
-        Camera(int id);
+        explicit Camera(int id);
         virtual ~Camera();
 
         // Common Camera Device Operations (see <hardware/camera_common.h>)
diff --git a/modules/camera/CameraHAL.cpp b/modules/camera/3_0/CameraHAL.cpp
similarity index 84%
rename from modules/camera/CameraHAL.cpp
rename to modules/camera/3_0/CameraHAL.cpp
index 62ee6d4..e395ce5 100644
--- a/modules/camera/CameraHAL.cpp
+++ b/modules/camera/3_0/CameraHAL.cpp
@@ -165,29 +165,29 @@
 }
 
 static hw_module_methods_t gCameraModuleMethods = {
-    open : open_dev
+    .open = open_dev
 };
 
 camera_module_t HAL_MODULE_INFO_SYM __attribute__ ((visibility("default"))) = {
-    common : {
-        tag                : HARDWARE_MODULE_TAG,
-        module_api_version : CAMERA_MODULE_API_VERSION_2_2,
-        hal_api_version    : HARDWARE_HAL_API_VERSION,
-        id                 : CAMERA_HARDWARE_MODULE_ID,
-        name               : "Default Camera HAL",
-        author             : "The Android Open Source Project",
-        methods            : &gCameraModuleMethods,
-        dso                : NULL,
-        reserved           : {0},
+    .common = {
+        .tag                = HARDWARE_MODULE_TAG,
+        .module_api_version = CAMERA_MODULE_API_VERSION_2_2,
+        .hal_api_version    = HARDWARE_HAL_API_VERSION,
+        .id                 = CAMERA_HARDWARE_MODULE_ID,
+        .name               = "Default Camera HAL",
+        .author             = "The Android Open Source Project",
+        .methods            = &gCameraModuleMethods,
+        .dso                = NULL,
+        .reserved           = {0},
     },
-    get_number_of_cameras : get_number_of_cameras,
-    get_camera_info       : get_camera_info,
-    set_callbacks         : set_callbacks,
-    get_vendor_tag_ops    : get_vendor_tag_ops,
-    open_legacy           : NULL,
-    set_torch_mode        : NULL,
-    init                  : NULL,
-    reserved              : {0},
+    .get_number_of_cameras = get_number_of_cameras,
+    .get_camera_info       = get_camera_info,
+    .set_callbacks         = set_callbacks,
+    .get_vendor_tag_ops    = get_vendor_tag_ops,
+    .open_legacy           = NULL,
+    .set_torch_mode        = NULL,
+    .init                  = NULL,
+    .reserved              = {0},
 };
 } // extern "C"
 
diff --git a/modules/camera/CameraHAL.h b/modules/camera/3_0/CameraHAL.h
similarity index 97%
rename from modules/camera/CameraHAL.h
rename to modules/camera/3_0/CameraHAL.h
index 00c74e5..74a70a6 100644
--- a/modules/camera/CameraHAL.h
+++ b/modules/camera/3_0/CameraHAL.h
@@ -29,7 +29,7 @@
 // camera device.
 class CameraHAL {
     public:
-        CameraHAL(int num_cameras);
+        explicit CameraHAL(int num_cameras);
         ~CameraHAL();
 
         // Camera Module Interface (see <hardware/camera_common.h>)
diff --git a/modules/camera/ExampleCamera.cpp b/modules/camera/3_0/ExampleCamera.cpp
similarity index 98%
rename from modules/camera/ExampleCamera.cpp
rename to modules/camera/3_0/ExampleCamera.cpp
index d873321..d060d35 100644
--- a/modules/camera/ExampleCamera.cpp
+++ b/modules/camera/3_0/ExampleCamera.cpp
@@ -26,7 +26,7 @@
 
 #include "ExampleCamera.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 namespace default_camera_hal {
 
@@ -264,7 +264,8 @@
     return setTemplate(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG, m.get());
 }
 
-bool ExampleCamera::isValidCaptureSettings(const camera_metadata_t* settings)
+bool ExampleCamera::isValidCaptureSettings(
+        const camera_metadata_t* /*settings*/)
 {
     // TODO: reject settings that cannot be captured
     return true;
diff --git a/modules/camera/ExampleCamera.h b/modules/camera/3_0/ExampleCamera.h
similarity index 97%
rename from modules/camera/ExampleCamera.h
rename to modules/camera/3_0/ExampleCamera.h
index 45c4a94..44eac76 100644
--- a/modules/camera/ExampleCamera.h
+++ b/modules/camera/3_0/ExampleCamera.h
@@ -27,7 +27,7 @@
 // metadata and logic about that device.
 class ExampleCamera : public Camera {
     public:
-        ExampleCamera(int id);
+        explicit ExampleCamera(int id);
         ~ExampleCamera();
 
     private:
diff --git a/modules/camera/Metadata.cpp b/modules/camera/3_0/Metadata.cpp
similarity index 100%
rename from modules/camera/Metadata.cpp
rename to modules/camera/3_0/Metadata.cpp
diff --git a/modules/camera/Metadata.h b/modules/camera/3_0/Metadata.h
similarity index 100%
rename from modules/camera/Metadata.h
rename to modules/camera/3_0/Metadata.h
diff --git a/modules/camera/Stream.cpp b/modules/camera/3_0/Stream.cpp
similarity index 100%
rename from modules/camera/Stream.cpp
rename to modules/camera/3_0/Stream.cpp
diff --git a/modules/camera/Stream.h b/modules/camera/3_0/Stream.h
similarity index 100%
rename from modules/camera/Stream.h
rename to modules/camera/3_0/Stream.h
diff --git a/modules/camera/VendorTags.cpp b/modules/camera/3_0/VendorTags.cpp
similarity index 91%
rename from modules/camera/VendorTags.cpp
rename to modules/camera/3_0/VendorTags.cpp
index 2c54648..48c1a46 100644
--- a/modules/camera/VendorTags.cpp
+++ b/modules/camera/3_0/VendorTags.cpp
@@ -136,12 +136,13 @@
 {
 }
 
-int VendorTags::getTagCount(const vendor_tag_ops_t* ops)
+int VendorTags::getTagCount(const vendor_tag_ops_t* /*ops*/)
 {
     return mTagCount;
 }
 
-void VendorTags::getAllTags(const vendor_tag_ops_t* ops, uint32_t* tag_array)
+void VendorTags::getAllTags(const vendor_tag_ops_t* /*ops*/,
+        uint32_t* tag_array)
 {
     if (tag_array == NULL) {
         ALOGE("%s: NULL tag_array", __func__);
@@ -156,7 +157,8 @@
     }
 }
 
-const char* VendorTags::getSectionName(const vendor_tag_ops_t* ops, uint32_t tag)
+const char* VendorTags::getSectionName(const vendor_tag_ops_t* /*ops*/,
+        uint32_t tag)
 {
     const Section* section = getSection(tag);
 
@@ -166,7 +168,8 @@
     return section->name;
 }
 
-const char* VendorTags::getTagName(const vendor_tag_ops_t* ops, uint32_t tag)
+const char* VendorTags::getTagName(const vendor_tag_ops_t* /*ops*/,
+        uint32_t tag)
 {
     const Entry* entry = getEntry(tag);
 
@@ -176,7 +179,7 @@
     return entry->name;
 }
 
-int VendorTags::getTagType(const vendor_tag_ops_t* ops, uint32_t tag)
+int VendorTags::getTagType(const vendor_tag_ops_t* /*ops*/, uint32_t tag)
 {
     const Entry* entry = getEntry(tag);
 
diff --git a/modules/camera/VendorTags.h b/modules/camera/3_0/VendorTags.h
similarity index 100%
rename from modules/camera/VendorTags.h
rename to modules/camera/3_0/VendorTags.h
diff --git a/modules/camera/Android.mk b/modules/camera/Android.mk
index ae68ed5..71388aa 100644
--- a/modules/camera/Android.mk
+++ b/modules/camera/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 The Android Open Source Project
+# Copyright (C) 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -12,34 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := camera.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-
-LOCAL_C_INCLUDES += \
-	system/core/include \
-	system/media/camera/include \
-
-LOCAL_SRC_FILES := \
-	CameraHAL.cpp \
-	Camera.cpp \
-	ExampleCamera.cpp \
-	Metadata.cpp \
-	Stream.cpp \
-	VendorTags.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-	libcamera_metadata \
-	libcutils \
-	liblog \
-	libsync \
-	libutils \
-
-LOCAL_CFLAGS += -Wall -Wextra -fvisibility=hidden
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
+include $(call all-subdir-makefiles)
diff --git a/modules/consumerir/Android.bp b/modules/consumerir/Android.bp
new file mode 100644
index 0000000..b139492
--- /dev/null
+++ b/modules/consumerir/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "consumerir.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["consumerir.c"],
+    shared_libs: [
+        "liblog",
+    ],
+}
diff --git a/modules/consumerir/Android.mk b/modules/consumerir/Android.mk
deleted file mode 100644
index b881572..0000000
--- a/modules/consumerir/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := consumerir.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := consumerir.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/consumerir/consumerir.c b/modules/consumerir/consumerir.c
index f3eac0b..2af6b89 100644
--- a/modules/consumerir/consumerir.c
+++ b/modules/consumerir/consumerir.c
@@ -18,11 +18,11 @@
 #include <errno.h>
 #include <malloc.h>
 #include <string.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <hardware/hardware.h>
 #include <hardware/consumerir.h>
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 static const consumerir_freq_range_t consumerir_freqs[] = {
     {.min = 30000, .max = 30000},
diff --git a/modules/fingerprint/Android.bp b/modules/fingerprint/Android.bp
new file mode 100644
index 0000000..ba749e4
--- /dev/null
+++ b/modules/fingerprint/Android.bp
@@ -0,0 +1,21 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "fingerprint.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["fingerprint.c"],
+    shared_libs: ["liblog"],
+}
diff --git a/modules/fingerprint/Android.mk b/modules/fingerprint/Android.mk
deleted file mode 100644
index 58c0a83..0000000
--- a/modules/fingerprint/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := fingerprint.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := fingerprint.c
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index 092e851..ff5808d 100644
--- a/modules/gralloc/Android.mk
+++ b/modules/gralloc/Android.mk
@@ -20,6 +20,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SHARED_LIBRARIES := liblog libcutils
 
 LOCAL_SRC_FILES := 	\
@@ -27,6 +28,8 @@
 	framebuffer.cpp \
 	mapper.cpp
 
+LOCAL_HEADER_LIBRARIES := libhardware_headers
+
 LOCAL_MODULE := gralloc.default
 LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -Wno-missing-field-initializers
 ifeq ($(TARGET_USE_PAN_DISPLAY),true)
diff --git a/modules/gralloc/gr.h b/modules/gralloc/gr.h
index 732b6bc..ac7e967 100644
--- a/modules/gralloc/gr.h
+++ b/modules/gralloc/gr.h
@@ -48,7 +48,7 @@
     class Autolock {
         Locker& locker;
     public:
-        inline Autolock(Locker& locker) : locker(locker) {  locker.lock(); }
+        inline explicit Autolock(Locker& locker) : locker(locker) {  locker.lock(); }
         inline ~Autolock() { locker.unlock(); }
     };
     inline Locker()        { pthread_mutex_init(&mutex, 0); }
diff --git a/modules/gralloc/gralloc.cpp b/modules/gralloc/gralloc.cpp
index e9559e9..84133fd 100644
--- a/modules/gralloc/gralloc.cpp
+++ b/modules/gralloc/gralloc.cpp
@@ -210,6 +210,9 @@
 
     int bytesPerPixel = 0;
     switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_FP16:
+            bytesPerPixel = 8;
+            break;
         case HAL_PIXEL_FORMAT_RGBA_8888:
         case HAL_PIXEL_FORMAT_RGBX_8888:
         case HAL_PIXEL_FORMAT_BGRA_8888:
diff --git a/modules/hwcomposer/Android.mk b/modules/hwcomposer/Android.mk
index 35c0fae..da0f6db 100644
--- a/modules/hwcomposer/Android.mk
+++ b/modules/hwcomposer/Android.mk
@@ -20,6 +20,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SHARED_LIBRARIES := liblog libEGL
 LOCAL_SRC_FILES := hwcomposer.cpp
 LOCAL_MODULE := hwcomposer.default
diff --git a/modules/hwcomposer/hwcomposer.cpp b/modules/hwcomposer/hwcomposer.cpp
index 9d1aa34..7b2e278 100644
--- a/modules/hwcomposer/hwcomposer.cpp
+++ b/modules/hwcomposer/hwcomposer.cpp
@@ -38,18 +38,18 @@
         struct hw_device_t** device);
 
 static struct hw_module_methods_t hwc_module_methods = {
-    open: hwc_device_open
+    .open = hwc_device_open
 };
 
 hwc_module_t HAL_MODULE_INFO_SYM = {
-    common: {
-        tag: HARDWARE_MODULE_TAG,
-        version_major: 1,
-        version_minor: 0,
-        id: HWC_HARDWARE_MODULE_ID,
-        name: "Sample hwcomposer module",
-        author: "The Android Open Source Project",
-        methods: &hwc_module_methods,
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .version_major = 1,
+        .version_minor = 0,
+        .id = HWC_HARDWARE_MODULE_ID,
+        .name = "Sample hwcomposer module",
+        .author = "The Android Open Source Project",
+        .methods = &hwc_module_methods,
     }
 };
 
@@ -68,8 +68,8 @@
             l->displayFrame.bottom);
 }
 
-static int hwc_prepare(hwc_composer_device_1_t *dev,
-        size_t numDisplays, hwc_display_contents_1_t** displays) {
+static int hwc_prepare(hwc_composer_device_1_t * /*dev*/,
+        size_t /*numDisplays*/, hwc_display_contents_1_t** displays) {
     if (displays && (displays[0]->flags & HWC_GEOMETRY_CHANGED)) {
         for (size_t i=0 ; i<displays[0]->numHwLayers ; i++) {
             //dump_layer(&list->hwLayers[i]);
@@ -79,16 +79,16 @@
     return 0;
 }
 
-static int hwc_set(hwc_composer_device_1_t *dev,
-        size_t numDisplays, hwc_display_contents_1_t** displays)
+static int hwc_set(hwc_composer_device_1_t * /*dev*/,
+        size_t /*numDisplays*/, hwc_display_contents_1_t** displays)
 {
     //for (size_t i=0 ; i<list->numHwLayers ; i++) {
     //    dump_layer(&list->hwLayers[i]);
     //}
 
-    EGLBoolean sucess = eglSwapBuffers((EGLDisplay)displays[0]->dpy,
+    EGLBoolean success = eglSwapBuffers((EGLDisplay)displays[0]->dpy,
             (EGLSurface)displays[0]->sur);
-    if (!sucess) {
+    if (!success) {
         return HWC_EGL_ERROR;
     }
     return 0;
diff --git a/modules/input/evdev/Android.mk b/modules/input/evdev/Android.mk
index 9a5d092..be4db6b 100644
--- a/modules/input/evdev/Android.mk
+++ b/modules/input/evdev/Android.mk
@@ -45,6 +45,7 @@
 
 LOCAL_MODULE := input.evdev.default
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_SRC_FILES := \
     EvdevModule.cpp
diff --git a/modules/input/evdev/InputHub.cpp b/modules/input/evdev/InputHub.cpp
index 389955d..e2c65fa 100644
--- a/modules/input/evdev/InputHub.cpp
+++ b/modules/input/evdev/InputHub.cpp
@@ -610,7 +610,7 @@
             for (;;) {
                 ssize_t readSize = TEMP_FAILURE_RETRY(read(inputFd, ievs, sizeof(ievs)));
                 if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
-                    ALOGW("could not get event, removed? (fd: %d, size: %d errno: %d)",
+                    ALOGW("could not get event, removed? (fd: %d, size: %zd errno: %d)",
                             inputFd, readSize, errno);
 
                     removedDeviceFds.push_back(inputFd);
@@ -621,7 +621,7 @@
                     }
                     break;
                 } else if (readSize % sizeof(input_event) != 0) {
-                    ALOGE("could not get event. wrong size=%d", readSize);
+                    ALOGE("could not get event. wrong size=%zd", readSize);
                     break;
                 } else {
                     size_t count = static_cast<size_t>(readSize) / sizeof(struct input_event);
@@ -702,7 +702,7 @@
             if (event->mask & IN_CREATE) {
                 auto deviceNode = openNode(path);
                 if (deviceNode == nullptr) {
-                    ALOGE("could not open device node %s. err=%d", path.c_str(), res);
+                    ALOGE("could not open device node %s. err=%zd", path.c_str(), res);
                 } else {
                     mInputCallback->onDeviceAdded(deviceNode);
                 }
diff --git a/modules/local_time/Android.bp b/modules/local_time/Android.bp
new file mode 100644
index 0000000..643afa5
--- /dev/null
+++ b/modules/local_time/Android.bp
@@ -0,0 +1,33 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// The default local time HAL module.  The default module simply uses the
+// system's clock_gettime(CLOCK_MONOTONIC) and does not support HW slewing.
+// Devices which use the default implementation should take care to ensure that
+// the oscillator backing the CLOCK_MONOTONIC implementation is phase locked to
+// the audio and video output hardware.  This default implementation is loaded
+// if no other device specific modules are present. The exact load order can be
+// seen in libhardware/hardware.c
+//
+// The format of the name is local_time.<hardware>.so
+cc_library_shared {
+    name: "local_time.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["local_time_hw.c"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+    ],
+}
diff --git a/modules/local_time/Android.mk b/modules/local_time/Android.mk
deleted file mode 100644
index 91885aa..0000000
--- a/modules/local_time/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# The default local time HAL module.  The default module simply uses the
-# system's clock_gettime(CLOCK_MONOTONIC) and does not support HW slewing.
-# Devices which use the default implementation should take care to ensure that
-# the oscillator backing the CLOCK_MONOTONIC implementation is phase locked to
-# the audio and video output hardware.  This default implementation is loaded
-# if no other device specific modules are present. The exact load order can be
-# seen in libhardware/hardware.c
-#
-# The format of the name is local_time.<hardware>.so
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := local_time.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := local_time_hw.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/local_time/local_time_hw.c b/modules/local_time/local_time_hw.c
index ac597f4..899c38a 100644
--- a/modules/local_time/local_time_hw.c
+++ b/modules/local_time/local_time_hw.c
@@ -28,6 +28,9 @@
 #include <hardware/hardware.h>
 #include <hardware/local_time_hal.h>
 
+// We only support gcc and clang, both of which support this attribute.
+#define UNUSED_ARGUMENT __attribute((unused))
+
 struct stub_local_time_device {
     struct local_time_hw_device device;
 };
@@ -51,7 +54,8 @@
     return (int64_t)now;
 }
 
-static uint64_t ltdev_get_local_freq(struct local_time_hw_device* dev)
+static uint64_t ltdev_get_local_freq(
+        struct local_time_hw_device* dev UNUSED_ARGUMENT)
 {
     // For better or worse, linux clock_gettime routines normalize all clock
     // frequencies to 1GHz
diff --git a/modules/nfc-nci/Android.bp b/modules/nfc-nci/Android.bp
new file mode 100644
index 0000000..90d2a28
--- /dev/null
+++ b/modules/nfc-nci/Android.bp
@@ -0,0 +1,24 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "nfc_nci.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["nfc_nci_example.c"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+    ],
+}
diff --git a/modules/nfc-nci/Android.mk b/modules/nfc-nci/Android.mk
deleted file mode 100644
index c1f679a..0000000
--- a/modules/nfc-nci/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := nfc_nci.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := nfc_nci_example.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/nfc-nci/nfc_nci_example.c b/modules/nfc-nci/nfc_nci_example.c
index 758c2b7..ea5eb47 100644
--- a/modules/nfc-nci/nfc_nci_example.c
+++ b/modules/nfc-nci/nfc_nci_example.c
@@ -23,44 +23,61 @@
 
 
 /*
+ * We want to silence the "unused argument" that gcc and clang give.
+ * Other compilers generating this warning will need to provide their
+ * custom attribute to silence this.
+ */
+#if defined(__GNUC__) || defined(__clang__)
+#define UNUSED_ARGUMENT __attribute((unused))
+#else
+#define UNUSED_ARGUMENT
+#endif
+
+/*
  * NCI HAL method implementations. These must be overriden
  */
-static int hal_open(const struct nfc_nci_device *dev,
-        nfc_stack_callback_t *p_cback, nfc_stack_data_callback_t *p_data_cback) {
+static int hal_open(const struct nfc_nci_device *dev UNUSED_ARGUMENT,
+        nfc_stack_callback_t *p_cback UNUSED_ARGUMENT,
+        nfc_stack_data_callback_t *p_data_cback UNUSED_ARGUMENT) {
     ALOGE("NFC-NCI HAL: %s", __FUNCTION__);
     return 0;
 }
 
-static int hal_write(const struct nfc_nci_device *dev,
-        uint16_t data_len, const uint8_t *p_data) {
+static int hal_write(const struct nfc_nci_device *dev UNUSED_ARGUMENT,
+        uint16_t data_len UNUSED_ARGUMENT,
+        const uint8_t *p_data UNUSED_ARGUMENT) {
     ALOGE("NFC-NCI HAL: %s", __FUNCTION__);
     return 0;
 }
 
-static int hal_core_initialized(const struct nfc_nci_device *dev,
-        uint8_t* p_core_init_rsp_params) {
+static int hal_core_initialized(
+        const struct nfc_nci_device *dev UNUSED_ARGUMENT,
+        uint8_t* p_core_init_rsp_params UNUSED_ARGUMENT) {
     ALOGE("NFC-NCI HAL: %s", __FUNCTION__);
     return 0;
 }
 
-static int hal_pre_discover(const struct nfc_nci_device *dev) {
+static int hal_pre_discover(
+        const struct nfc_nci_device *dev UNUSED_ARGUMENT) {
     ALOGE("NFC-NCI HAL: %s", __FUNCTION__);
     return 0;
 }
 
-static int hal_close(const struct nfc_nci_device *dev) {
+static int hal_close(const struct nfc_nci_device *dev UNUSED_ARGUMENT) {
     ALOGE("NFC-NCI HAL: %s", __FUNCTION__);
     return 0;
 }
 
-static int hal_control_granted (const struct nfc_nci_device *p_dev)
+static int hal_control_granted (
+        const struct nfc_nci_device *p_dev UNUSED_ARGUMENT)
 {
     ALOGE("NFC-NCI HAL: %s", __FUNCTION__);
     return 0;
 }
 
 
-static int hal_power_cycle (const struct nfc_nci_device *p_dev)
+static int hal_power_cycle (
+        const struct nfc_nci_device *p_dev UNUSED_ARGUMENT)
 {
     ALOGE("NFC-NCI HAL: %s", __FUNCTION__);
     return 0;
diff --git a/modules/nfc/Android.bp b/modules/nfc/Android.bp
new file mode 100644
index 0000000..10dc2c1
--- /dev/null
+++ b/modules/nfc/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "nfc.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["nfc_pn544_example.c"],
+    shared_libs: [
+        "liblog",
+    ],
+}
diff --git a/modules/nfc/Android.mk b/modules/nfc/Android.mk
deleted file mode 100644
index 29b239c..0000000
--- a/modules/nfc/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := nfc.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := nfc_pn544_example.c
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/power/Android.bp b/modules/power/Android.bp
new file mode 100644
index 0000000..f4c74ce
--- /dev/null
+++ b/modules/power/Android.bp
@@ -0,0 +1,21 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "power.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: ["power.c"],
+    shared_libs: ["liblog"],
+}
diff --git a/modules/power/Android.mk b/modules/power/Android.mk
deleted file mode 100644
index c868ded..0000000
--- a/modules/power/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := power.default
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := power.c
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/power/power.c b/modules/power/power.c
index 7cacc09..15d7ba2 100644
--- a/modules/power/power.c
+++ b/modules/power/power.c
@@ -25,16 +25,21 @@
 #include <hardware/hardware.h>
 #include <hardware/power.h>
 
-static void power_init(struct power_module *module)
+// We only support clang and g++.
+#define UNUSED_ARGUMENT __attribute((unused))
+
+static void power_init(struct power_module *module UNUSED_ARGUMENT)
 {
 }
 
-static void power_set_interactive(struct power_module *module, int on)
+static void power_set_interactive(struct power_module *module UNUSED_ARGUMENT,
+                                  int on UNUSED_ARGUMENT)
 {
 }
 
-static void power_hint(struct power_module *module, power_hint_t hint,
-                       void *data) {
+static void power_hint(struct power_module *module UNUSED_ARGUMENT,
+                       power_hint_t hint,
+                       void *data UNUSED_ARGUMENT) {
     switch (hint) {
     default:
         break;
diff --git a/modules/radio/Android.mk b/modules/radio/Android.mk
index 221424f..6f11169 100644
--- a/modules/radio/Android.mk
+++ b/modules/radio/Android.mk
@@ -21,6 +21,7 @@
 
 LOCAL_MODULE := radio.fm.default
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SRC_FILES := radio_hw.c
 LOCAL_SHARED_LIBRARIES := liblog libcutils libradio_metadata
 LOCAL_MODULE_TAGS := optional
diff --git a/modules/radio/radio_hal_tool.c b/modules/radio/radio_hal_tool.c
index 05d872e..6c40739 100644
--- a/modules/radio/radio_hal_tool.c
+++ b/modules/radio/radio_hal_tool.c
@@ -131,7 +131,7 @@
         radio_metadata_key_t key;
         radio_metadata_type_t type;
         void *value;
-        uint32_t size;
+        size_t size;
 
         radio_metadata_get_at_index(info.metadata, i, &key, &type, &value, &size);
 
diff --git a/modules/radio/radio_hw.c b/modules/radio/radio_hw.c
index fbf8c94..4010507 100644
--- a/modules/radio/radio_hw.c
+++ b/modules/radio/radio_hw.c
@@ -47,7 +47,7 @@
     .bands = {
         {
             .type = RADIO_BAND_FM,
-            .antenna_connected = false,
+            .antenna_connected = true,
             .lower_limit = 87900,
             .upper_limit = 107900,
             .num_spacings = 1,
@@ -189,7 +189,7 @@
 exit:
     close(fd);
     free(data);
-    ALOGE_IF(ret != 0, "%s error %d", __func__, ret);
+    ALOGE_IF(ret != 0, "%s error %d", __func__, (int)ret);
     return (int)ret;
 }
 
@@ -209,6 +209,7 @@
     *metadata = NULL;
 
     ret = radio_metadata_allocate(metadata, tuner->program.channel, 0);
+
     if (ret != 0)
         return ret;
 
@@ -220,14 +221,14 @@
         if (ret != 0)
             goto exit;
         ret = add_bitmap_metadata(metadata, RADIO_METADATA_KEY_ICON, BITMAP_FILE_PATH);
-        if (ret != 0)
+        if (ret != 0 && ret != -EPIPE)
             goto exit;
         ret = radio_metadata_add_clock(metadata, RADIO_METADATA_KEY_CLOCK, &hw_clock);
         if (ret != 0)
             goto exit;
     } else {
         ret = add_bitmap_metadata(metadata, RADIO_METADATA_KEY_ART, BITMAP_FILE_PATH);
-        if (ret != 0)
+        if (ret != 0 && ret != -EPIPE)
             goto exit;
     }
 
@@ -355,6 +356,7 @@
                         tuner->program.stereo = false;
                     else
                         tuner->program.stereo = false;
+                    prepare_metadata(tuner, &tuner->program.metadata, tuner->program.tuned);
 
                     event.type = RADIO_EVENT_TUNED;
                     event.info = tuner->program;
@@ -381,6 +383,7 @@
                     else
                         tuner->program.stereo = tuner->config.am.stereo;
                     tuner->program.signal_strength = 50;
+                    prepare_metadata(tuner, &tuner->program.metadata, tuner->program.tuned);
 
                     event.type = RADIO_EVENT_TUNED;
                     event.info = tuner->program;
@@ -393,12 +396,7 @@
                                                 (tuner->config.spacings[0] * 5)) % 2;
 
                     if (tuner->program.tuned) {
-                        prepare_metadata(tuner, &tuner->program.metadata, true);
                         send_command_l(tuner, CMD_ANNOUNCEMENTS, 1000, NULL);
-                    } else {
-                        if (tuner->program.metadata != NULL)
-                            radio_metadata_deallocate(tuner->program.metadata);
-                        tuner->program.metadata = NULL;
                     }
                     tuner->program.signal_strength = 100;
                     if (tuner->config.type == RADIO_BAND_FM)
@@ -407,6 +405,8 @@
                     else
                         tuner->program.stereo =
                             tuner->program.tuned ? tuner->config.am.stereo : false;
+                    prepare_metadata(tuner, &tuner->program.metadata, tuner->program.tuned);
+
                     event.type = RADIO_EVENT_TUNED;
                     event.info = tuner->program;
                     send_meta_data = true;
@@ -418,7 +418,6 @@
                         event.type = RADIO_EVENT_METADATA;
                         event.metadata = metadata;
                     }
-                    send_meta_data = true;
                 } break;
 
                 case CMD_CANCEL: {
@@ -502,6 +501,10 @@
         status = -EINVAL;
         goto exit;
     }
+    if (config->lower_limit > config->upper_limit) {
+        status = -EINVAL;
+        goto exit;
+    }
     send_command_l(stub_tuner, CMD_CANCEL, 0, NULL);
     send_command_l(stub_tuner, CMD_CONFIG, 500, (void *)config);
 
@@ -614,7 +617,12 @@
     metadata = info->metadata;
     *info = stub_tuner->program;
     info->metadata = metadata;
-    if (metadata != NULL && stub_tuner->program.metadata != NULL)
+    if (metadata == NULL) {
+        ALOGE("%s metadata is a nullptr", __func__);
+        status = -EINVAL;
+        goto exit;
+    }
+    if (stub_tuner->program.metadata != NULL)
         radio_metadata_add_metadata(&info->metadata, stub_tuner->program.metadata);
 
 exit:
diff --git a/modules/sensors/Android.bp b/modules/sensors/Android.bp
new file mode 100644
index 0000000..1d15065
--- /dev/null
+++ b/modules/sensors/Android.bp
@@ -0,0 +1,15 @@
+cc_library_static {
+    name: "multihal",
+    vendor: true,
+    srcs: [
+        "multihal.cpp",
+        "SensorEventQueue.cpp"
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libdl"
+    ],
+    export_include_dirs: ["."],
+}
diff --git a/modules/sensors/Android.mk b/modules/sensors/Android.mk
index 534e6e9..ca277e6 100644
--- a/modules/sensors/Android.mk
+++ b/modules/sensors/Android.mk
@@ -23,6 +23,7 @@
 LOCAL_MODULE := sensors.$(TARGET_DEVICE)
 
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_CFLAGS := -DLOG_TAG=\"MultiHal\"
 
diff --git a/modules/sensors/SensorEventQueue.h b/modules/sensors/SensorEventQueue.h
index 11e1f41..9778e93 100644
--- a/modules/sensors/SensorEventQueue.h
+++ b/modules/sensors/SensorEventQueue.h
@@ -38,7 +38,7 @@
     pthread_cond_t mSpaceAvailableCondition;
 
 public:
-    SensorEventQueue(int capacity);
+    explicit SensorEventQueue(int capacity);
     ~SensorEventQueue();
 
     // Returns length of region, between zero and min(capacity, requestedLength). If there is any
diff --git a/modules/sensors/dynamic_sensor/Android.mk b/modules/sensors/dynamic_sensor/Android.mk
new file mode 100644
index 0000000..4608508
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/Android.mk
@@ -0,0 +1,126 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+COMMON_CFLAGS := -Wall -Werror -Wextra
+
+dynamic_sensor_src := \
+    BaseDynamicSensorDaemon.cpp \
+    BaseSensorObject.cpp \
+    ConnectionDetector.cpp \
+    DummyDynamicAccelDaemon.cpp \
+    DynamicSensorManager.cpp \
+    HidRawDevice.cpp \
+    HidRawSensor.cpp \
+    HidRawSensorDaemon.cpp \
+    HidRawSensorDevice.cpp \
+    RingBuffer.cpp
+
+dynamic_sensor_shared_lib := \
+    libbase \
+    libcutils \
+    libhidparser \
+    liblog \
+    libutils
+#
+# There are two ways to utilize the dynamic sensor module:
+#   1. Use as an extension in an existing hal: declare dependency on libdynamic_sensor_ext shared
+#      library in existing sensor hal.
+#   2. Use as a standalone sensor HAL and configure multihal to combine it with sensor hal that
+#      hosts other sensors: add dependency on sensors.dynamic_sensor_hal in device level makefile and
+#      write multihal configuration file accordingly.
+#
+# Please take only one of these two options to avoid conflict over hardware resource.
+#
+#
+# Option 1: sensor extension module
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := libdynamic_sensor_ext
+LOCAL_MODULE_TAGS := optional
+# intended to be integrated into hal, thus proprietary
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorExt\"
+
+LOCAL_SRC_FILES := $(dynamic_sensor_src)
+
+LOCAL_SHARED_LIBRARIES := $(dynamic_sensor_shared_lib)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+include $(BUILD_SHARED_LIBRARY)
+
+#
+# Option 2: independent sensor hal
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := sensors.dynamic_sensor_hal
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+# hal module, thus proprietary
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorHal\"
+
+LOCAL_SRC_FILES := $(dynamic_sensor_src) sensors.cpp
+
+LOCAL_SHARED_LIBRARIES := $(dynamic_sensor_shared_lib)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+include $(BUILD_SHARED_LIBRARY)
+
+#
+# Host test for HidRawSensor. Test with dummy test HID descriptors.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidrawsensor_host_test
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+
+LOCAL_SRC_FILES := \
+    HidRawSensor.cpp \
+    BaseSensorObject.cpp \
+    HidUtils/test/TestHidDescriptor.cpp \
+    test/HidRawSensorTest.cpp
+
+LOCAL_SHARED_LIBRARIES := libhidparser_host
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test $(LOCAL_PATH)/HidUtils/test
+include $(BUILD_HOST_EXECUTABLE)
+
+#
+# Host test for HidRawDevice and HidRawSensor. Test with hidraw
+# device node.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidrawdevice_host_test
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+
+LOCAL_SRC_FILES := \
+    HidRawDevice.cpp \
+    HidRawSensor.cpp \
+    BaseSensorObject.cpp \
+    test/HidRawDeviceTest.cpp
+
+LOCAL_SHARED_LIBRARIES := libhidparser_host
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test $(LOCAL_PATH)/HidUtils/test
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(LOCAL_PATH)/HidUtils/Android.mk
diff --git a/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.cpp b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.cpp
new file mode 100644
index 0000000..7e9f217
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BaseDynamicSensorDaemon.h"
+#include "DynamicSensorManager.h"
+#include "utils/Log.h"
+
+namespace android {
+namespace SensorHalExt {
+
+bool BaseDynamicSensorDaemon::onConnectionChange(const std::string &deviceKey, bool connected) {
+    bool ret = false;
+    auto i = mDeviceKeySensorMap.find(deviceKey);
+    if (connected) {
+        if (i == mDeviceKeySensorMap.end()) {
+            ALOGV("device %s is connected", deviceKey.c_str());
+            // get sensors from implementation
+            BaseSensorVector sensors = createSensor(deviceKey);
+            if (sensors.empty()) {
+                ALOGI("no valid sensor is defined in device %s, ignore", deviceKey.c_str());
+            } else {
+                ALOGV("discovered %zu sensors from device", sensors.size());
+                // build internal table first
+                auto result = mDeviceKeySensorMap.emplace(deviceKey, std::move(sensors));
+                // then register sensor to dynamic sensor manager, result.first is the iterator
+                // of key-value pair; result.first->second is the value, which is s.
+                for (auto &i : result.first->second) {
+                    mManager.registerSensor(i);
+                }
+                ALOGV("device %s is registered", deviceKey.c_str());
+                ret = true;
+            }
+        } else {
+            ALOGD("device %s already added and is connected again, ignore", deviceKey.c_str());
+        }
+    } else {
+        ALOGV("device %s is disconnected", deviceKey.c_str());
+        if (i != mDeviceKeySensorMap.end()) {
+            BaseSensorVector sensors = i->second;
+            for (auto &sensor : sensors) {
+                mManager.unregisterSensor(sensor);
+            }
+            mDeviceKeySensorMap.erase(i);
+            // notify implementation
+            removeSensor(deviceKey);
+            ALOGV("device %s is unregistered", deviceKey.c_str());
+            ret = true;
+        } else {
+            ALOGV("device not found in registry");
+        }
+    }
+
+    return ret;
+}
+} // namespace SensorHalExt
+} // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h
new file mode 100644
index 0000000..0cec965
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_BASE_DYNAMIC_SENSOR_DAEMON_H
+#define ANDROID_SENSORHAL_EXT_BASE_DYNAMIC_SENSOR_DAEMON_H
+
+#include "BaseSensorObject.h"
+
+#include <utils/RefBase.h>
+#include <string>
+#include <unordered_map>
+
+namespace android {
+namespace SensorHalExt {
+
+class DynamicSensorManager;
+
+typedef std::vector<sp<BaseSensorObject>> BaseSensorVector;
+
+class BaseDynamicSensorDaemon : public RefBase {
+public:
+    BaseDynamicSensorDaemon(DynamicSensorManager& manager) : mManager(manager) {}
+    virtual ~BaseDynamicSensorDaemon() = default;
+
+    virtual bool onConnectionChange(const std::string &deviceKey, bool connected);
+protected:
+    virtual BaseSensorVector createSensor(const std::string &deviceKey) = 0;
+    virtual void removeSensor(const std::string &/*deviceKey*/) {};
+
+    DynamicSensorManager &mManager;
+    std::unordered_map<std::string, BaseSensorVector> mDeviceKeySensorMap;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_BASE_DYNAMIC_SENSOR_DAEMON_H
+
diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
new file mode 100644
index 0000000..4ec76b2
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BaseSensorObject.h"
+#include "SensorEventCallback.h"
+#include "Utils.h"
+
+#include <cstring>
+
+namespace android {
+namespace SensorHalExt {
+
+BaseSensorObject::BaseSensorObject() : mCallback(nullptr) {
+}
+
+bool BaseSensorObject::setEventCallback(SensorEventCallback* callback) {
+    if (mCallback != nullptr) {
+        return false;
+    }
+    mCallback = callback;
+    return true;
+}
+
+void BaseSensorObject::getUuid(uint8_t* uuid) const {
+    // default uuid denoting uuid feature is not supported on this sensor.
+    memset(uuid, 0, 16);
+}
+
+int BaseSensorObject::flush() {
+    static const sensors_event_t event = {
+        .type = SENSOR_TYPE_META_DATA,
+        .timestamp = TIMESTAMP_AUTO_FILL  // timestamp will be filled at dispatcher
+    };
+    generateEvent(event);
+    return 0;
+}
+
+void BaseSensorObject::generateEvent(const sensors_event_t &e) {
+    if (mCallback) {
+        mCallback->submitEvent(SP_THIS, e);
+    }
+}
+
+} // namespace SensorHalExt
+} // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.h b/modules/sensors/dynamic_sensor/BaseSensorObject.h
new file mode 100644
index 0000000..e8d1a5d
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/BaseSensorObject.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
+#define ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
+
+#include "Utils.h"
+#include <cstdint>
+
+struct sensor_t;
+struct sensors_event_t;
+
+namespace android {
+namespace SensorHalExt {
+
+class SensorEventCallback;
+
+class BaseSensorObject : virtual public REF_BASE(BaseSensorObject) {
+public:
+    BaseSensorObject();
+    virtual ~BaseSensorObject() = default;
+
+    // always called by DynamicSensorManager, callback must point to
+    // valid object throughout life cycle of BaseSensorObject
+    bool setEventCallback(SensorEventCallback* callback);
+
+    // virtual functions to get sensor information and operate sensor
+    virtual const sensor_t* getSensor() const = 0;
+
+    // get uuid of sensor, default implementation set it to all zero, means does not have a uuid.
+    virtual void getUuid(uint8_t* uuid) const;
+
+    // enable sensor
+    virtual int enable(bool enable) = 0;
+
+    // set sample period and batching period of sensor.
+    // both sample period and batch period are in nano-seconds.
+    virtual int batch(int64_t samplePeriod, int64_t batchPeriod) = 0;
+
+    // flush sensor, default implementation will send a flush complete event back.
+    virtual int flush();
+
+protected:
+    // utility function for sub-class
+    void generateEvent(const sensors_event_t &e);
+private:
+    SensorEventCallback* mCallback;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
+
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
new file mode 100644
index 0000000..67a6f27
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ConnectionDetector.h"
+
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/inotify.h>
+#include <sys/socket.h>
+
+#include <sstream>
+
+namespace android {
+namespace SensorHalExt {
+
+// SocketConnectionDetector functions
+SocketConnectionDetector::SocketConnectionDetector(BaseDynamicSensorDaemon *d, int port)
+        : ConnectionDetector(d), Thread(false /*canCallJava*/) {
+    // initialize socket that accept connection to localhost:port
+    mListenFd = ::socket(AF_INET, SOCK_STREAM, 0);
+    if (mListenFd < 0) {
+        ALOGE("Cannot open socket");
+        return;
+    }
+
+    struct sockaddr_in serverAddress = {
+        .sin_family = AF_INET,
+        .sin_port = htons(port),
+        .sin_addr = {
+            .s_addr = htonl(INADDR_LOOPBACK)
+        }
+    };
+
+    ::bind(mListenFd, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
+    if (::listen(mListenFd, 0) != NO_ERROR) {
+        ALOGE("Cannot listen to port %d", port);
+        mListenFd = -1;
+        return;
+    }
+
+    std::ostringstream s;
+    s << "socket:" << port;
+    mDevice = s.str();
+
+    run("ddad_socket");
+}
+
+SocketConnectionDetector::~SocketConnectionDetector() {
+    if (mListenFd >= 0) {
+        requestExitAndWait();
+    }
+}
+
+int SocketConnectionDetector::waitForConnection() {
+    return ::accept(mListenFd, nullptr, nullptr);
+}
+
+void SocketConnectionDetector::waitForDisconnection(int connFd) {
+    char buffer[16];
+    while (::read(connFd, buffer, sizeof(buffer)) > 0) {
+        // discard data but response something to denote thread alive
+        ::write(connFd, ".", 1);
+    }
+    // read failure means disconnection
+    ::close(connFd);
+}
+
+bool SocketConnectionDetector::threadLoop() {
+    while (!Thread::exitPending()) {
+        // block waiting for connection
+        int connFd = waitForConnection();
+
+        if (connFd < 0) {
+            break;
+        }
+
+        ALOGV("Received connection, register dynamic accel sensor");
+        mDaemon->onConnectionChange(mDevice, true);
+
+        waitForDisconnection(connFd);
+        ALOGV("Connection break, unregister dynamic accel sensor");
+        mDaemon->onConnectionChange(mDevice, false);
+    }
+    mDaemon->onConnectionChange(mDevice, false);
+    ALOGD("SocketConnectionDetector thread exited");
+    return false;
+}
+
+// FileConnectionDetector functions
+FileConnectionDetector::FileConnectionDetector (
+        BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex)
+            : ConnectionDetector(d), Thread(false /*callCallJava*/), mPath(path), mRegex(regex) {
+    mInotifyFd = ::inotify_init1(IN_NONBLOCK);
+    if (mInotifyFd < 0) {
+        ALOGE("Cannot init inotify");
+        return;
+    }
+
+    int wd = ::inotify_add_watch(mInotifyFd, path.c_str(), IN_CREATE | IN_DELETE | IN_MOVED_FROM);
+    if (wd < 0) {
+        ::close(mInotifyFd);
+        mInotifyFd = -1;
+        ALOGE("Cannot setup watch on dir %s", path.c_str());
+        return;
+    }
+
+    mPollFd.fd = wd;
+    mPollFd.events = POLLIN;
+
+    run("ddad_file");
+}
+
+FileConnectionDetector::~FileConnectionDetector() {
+    if (mInotifyFd) {
+        requestExitAndWait();
+        ::close(mInotifyFd);
+    }
+}
+
+bool FileConnectionDetector::matches(const std::string &name) const {
+    return std::regex_match(name, mRegex);
+}
+
+std::string FileConnectionDetector::getFullName(const std::string name) const {
+    return mPath + name;
+}
+
+void FileConnectionDetector::processExistingFiles() const {
+    auto dirp = ::opendir(mPath.c_str());
+    struct dirent *dp;
+    while ((dp = ::readdir(dirp)) != NULL) {
+        const std::string name(dp->d_name);
+        if (matches(name)) {
+            mDaemon->onConnectionChange(getFullName(name), true /*connected*/);
+        }
+    }
+    ::closedir(dirp);
+}
+
+bool FileConnectionDetector::threadLoop() {
+    struct {
+        struct inotify_event e;
+        uint8_t padding[NAME_MAX + 1];
+    } ev;
+
+    processExistingFiles();
+
+    while (!Thread::exitPending()) {
+        int pollNum = ::poll(&mPollFd, 1, -1);
+        if (pollNum == -1) {
+           if (errno == EINTR)
+               continue;
+           ALOGE("inotify poll error: %s", ::strerror(errno));
+        }
+
+        if (pollNum > 0) {
+            if (! (mPollFd.revents & POLLIN)) {
+                continue;
+            }
+
+            /* Inotify events are available */
+            while (true) {
+                /* Read some events. */
+                ssize_t len = ::read(mInotifyFd, &ev, sizeof ev);
+                if (len == -1 && errno != EAGAIN) {
+                    ALOGE("read error: %s", ::strerror(errno));
+                    requestExit();
+                    break;
+                }
+
+                /* If the nonblocking read() found no events to read, then
+                   it returns -1 with errno set to EAGAIN. In that case,
+                   we exit the loop. */
+                if (len <= 0) {
+                    break;
+                }
+
+                if (ev.e.len && !(ev.e.mask & IN_ISDIR)) {
+                    const std::string name(ev.e.name);
+                    ALOGV("device %s state changed", name.c_str());
+                    if (matches(name)) {
+                        if (ev.e.mask & IN_CREATE) {
+                            mDaemon->onConnectionChange(getFullName(name), true /* connected*/);
+                        }
+
+                        if (ev.e.mask & IN_DELETE || ev.e.mask & IN_MOVED_FROM) {
+                            mDaemon->onConnectionChange(getFullName(name), false /* connected*/);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    ALOGD("FileConnectionDetection thread exited");
+    return false;
+}
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.h b/modules/sensors/dynamic_sensor/ConnectionDetector.h
new file mode 100644
index 0000000..712d832
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_CONNECTION_DETECTOR_H
+#define ANDROID_SENSORHAL_EXT_CONNECTION_DETECTOR_H
+
+#include "BaseDynamicSensorDaemon.h"
+#include <utils/Thread.h>
+
+#include <regex>
+
+#include <poll.h>
+
+namespace android {
+namespace SensorHalExt {
+
+// Abstraction of connection detector: an entity that calls
+// BaseDynamicSensorDaemon::onConnectionChange() when necessary.
+class ConnectionDetector : virtual public RefBase {
+public:
+    ConnectionDetector(BaseDynamicSensorDaemon *d) : mDaemon(d) { }
+    virtual ~ConnectionDetector() = default;
+protected:
+    BaseDynamicSensorDaemon* mDaemon;
+};
+
+// Open a socket that listen to localhost:port and notify sensor daemon of connection and
+// disconnection event when socket is connected or disconnected, respectively. Only one concurrent
+// client is accepted.
+class SocketConnectionDetector : public ConnectionDetector, public Thread {
+public:
+    SocketConnectionDetector(BaseDynamicSensorDaemon *d, int port);
+    virtual ~SocketConnectionDetector();
+private:
+    // implement virtual of Thread
+    virtual bool threadLoop();
+    int waitForConnection();
+    static void waitForDisconnection(int connFd);
+
+    int mListenFd;
+    std::string mDevice;
+};
+
+// Detect file change under path and notify sensor daemon of connection and disconnection event when
+// file is created in or removed from the directory, respectively.
+class FileConnectionDetector : public ConnectionDetector, public Thread {
+public:
+    FileConnectionDetector(
+            BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex);
+    virtual ~FileConnectionDetector();
+private:
+    // implement virtual of Thread
+    virtual bool threadLoop();
+
+    bool matches(const std::string &name) const;
+    void processExistingFiles() const;
+    std::string getFullName(const std::string name) const;
+
+    std::string mPath;
+    std::regex mRegex;
+    int mInotifyFd;
+    struct pollfd mPollFd;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_DAEMON_H
diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
new file mode 100644
index 0000000..a1a47e8
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BaseSensorObject.h"
+#include "ConnectionDetector.h"
+#include "DummyDynamicAccelDaemon.h"
+#include "DynamicSensorManager.h"
+
+#include <cutils/properties.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+#include <utils/misc.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <algorithm>            //std::max
+
+#define SYSPROP_PREFIX                  "dynamic_sensor.dummy"
+#define FILE_NAME_BASE                  "dummy_accel_file"
+#define FILE_NAME_REGEX                 ("^" FILE_NAME_BASE "[0-9]$")
+
+namespace android {
+namespace SensorHalExt {
+
+DummyDynamicAccelDaemon::DummyDynamicAccelDaemon(DynamicSensorManager& manager)
+        : BaseDynamicSensorDaemon(manager) {
+    char property[PROPERTY_VALUE_MAX+1];
+
+    property_get(SYSPROP_PREFIX ".file", property, "");
+    if (strcmp(property, "") != 0) {
+        mFileDetector = new FileConnectionDetector(
+                this, std::string(property), std::string(FILE_NAME_REGEX));
+    }
+
+    property_get(SYSPROP_PREFIX ".socket", property, "");
+    if (strcmp(property, "") != 0) {
+        mSocketDetector = new SocketConnectionDetector(this, atoi(property));
+    }
+}
+
+BaseSensorVector DummyDynamicAccelDaemon::createSensor(const std::string &deviceKey) {
+    BaseSensorVector ret;
+    if (deviceKey.compare(0, 1, "/") == 0) {
+        // file detector result, deviceKey is file absolute path
+        const size_t len = ::strlen(FILE_NAME_BASE) + 1; // +1 for number
+        if (deviceKey.length() < len) {
+            ALOGE("illegal file device key %s", deviceKey.c_str());
+        } else {
+            size_t start = deviceKey.length() - len;
+            ret.emplace_back(new DummySensor(deviceKey.substr(start)));
+        }
+    } else if (deviceKey.compare(0, ::strlen("socket:"), "socket:") == 0) {
+        ret.emplace_back(new DummySensor(deviceKey));
+    } else {
+        // unknown deviceKey
+        ALOGE("unknown deviceKey: %s", deviceKey.c_str());
+    }
+    return ret;
+}
+
+DummyDynamicAccelDaemon::DummySensor::DummySensor(const std::string &name)
+        : Thread(false /*canCallJava*/), mRunState(false) {
+    mSensorName = "Dummy Accel - " + name;
+    // fake sensor information for dummy sensor
+    mSensor = (struct sensor_t) {
+        mSensorName.c_str(),
+        "DemoSense, Inc.",
+        1,                                         // version
+        -1,                                        // handle, dummy number here
+        SENSOR_TYPE_ACCELEROMETER,
+        9.8 * 8.0f,                                // maxRange
+        9.8 * 8.0f / 32768.0f,                     // resolution
+        0.5f,                                      // power
+        (int32_t)(1.0E6f / 50),                    // minDelay
+        0,                                         // fifoReservedEventCount
+        0,                                         // fifoMaxEventCount
+        SENSOR_STRING_TYPE_ACCELEROMETER,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / 50),                       // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    };
+    mRunLock.lock();
+    run("DummySensor");
+}
+
+DummyDynamicAccelDaemon::DummySensor::~DummySensor() {
+    requestExitAndWait();
+    // unlock mRunLock so thread can be unblocked
+    mRunLock.unlock();
+}
+
+const sensor_t* DummyDynamicAccelDaemon::DummySensor::getSensor() const {
+    return &mSensor;
+}
+
+void DummyDynamicAccelDaemon::DummySensor::getUuid(uint8_t* uuid) const {
+    // at maximum, there will be always one instance, so we can hardcode
+    size_t hash = std::hash<std::string>()(mSensorName);
+    memset(uuid, 'x', 16);
+    memcpy(uuid, &hash, sizeof(hash));
+}
+
+int DummyDynamicAccelDaemon::DummySensor::enable(bool enable) {
+    std::lock_guard<std::mutex> lk(mLock);
+    if (mRunState != enable) {
+        if (enable) {
+            mRunLock.unlock();
+        } else {
+            mRunLock.lock();
+        }
+        mRunState = enable;
+    }
+    return 0;
+}
+
+int DummyDynamicAccelDaemon::DummySensor::batch(int64_t /*samplePeriod*/, int64_t /*batchPeriod*/) {
+    // Dummy sensor does not support changing rate and batching. But return successful anyway.
+    return 0;
+}
+
+void DummyDynamicAccelDaemon::DummySensor::waitUntilNextSample() {
+    // block when disabled (mRunLock locked)
+    mRunLock.lock();
+    mRunLock.unlock();
+
+    if (!Thread::exitPending()) {
+        // sleep 20 ms (50Hz)
+        usleep(20000);
+    }
+}
+
+bool DummyDynamicAccelDaemon::DummySensor::threadLoop() {
+    // designated intialization will leave the unspecified fields zeroed
+    sensors_event_t event = {
+        .version = sizeof(event),
+        .sensor = -1,
+        .type = SENSOR_TYPE_ACCELEROMETER,
+    };
+
+    int64_t startTimeNs = elapsedRealtimeNano();
+
+    ALOGI("Dynamic Dummy Accel started for sensor %s", mSensorName.c_str());
+    while (!Thread::exitPending()) {
+        waitUntilNextSample();
+
+        if (Thread::exitPending()) {
+            break;
+        }
+        int64_t nowTimeNs = elapsedRealtimeNano();
+        float t = (nowTimeNs - startTimeNs) / 1e9f;
+
+        event.data[0] = 2 * ::sin(3 * M_PI * t);
+        event.data[1] = 3 * ::cos(3 * M_PI * t);
+        event.data[2] = 1.5 * ::sin(6 * M_PI * t);
+        event.timestamp = nowTimeNs;
+        generateEvent(event);
+    }
+
+    ALOGI("Dynamic Dummy Accel thread ended for sensor %s", mSensorName.c_str());
+    return false;
+}
+
+} // namespace SensorHalExt
+} // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.h b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.h
new file mode 100644
index 0000000..95a5730
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_DUMMY_DYNAMIC_ACCEL_DAEMON_H
+#define ANDROID_SENSORHAL_EXT_DUMMY_DYNAMIC_ACCEL_DAEMON_H
+
+#include "BaseDynamicSensorDaemon.h"
+#include "BaseSensorObject.h"
+
+#include <hardware/sensors.h>
+#include <utils/Thread.h>
+#include <mutex>
+#include <unordered_set>
+
+namespace android {
+namespace SensorHalExt {
+
+class ConnectionDetector;
+
+/**
+ * This daemon simulates dynamic sensor connection without the need of actually connect peripheral
+ * to Android. It is for debugging and testing. It can handle one concurrent connections at maximum.
+ */
+class DummyDynamicAccelDaemon : public BaseDynamicSensorDaemon {
+public:
+    DummyDynamicAccelDaemon(DynamicSensorManager& manager);
+    virtual ~DummyDynamicAccelDaemon() = default;
+private:
+    class DummySensor : public BaseSensorObject, public Thread {
+    public:
+        DummySensor(const std::string &name);
+        ~DummySensor();
+        virtual const sensor_t* getSensor() const;
+        virtual void getUuid(uint8_t* uuid) const;
+        virtual int enable(bool enable);
+        virtual int batch(nsecs_t sample_period, nsecs_t batch_period);
+    private:
+        // implement Thread function
+        virtual bool threadLoop() override;
+
+        void waitUntilNextSample();
+
+        sensor_t mSensor;
+        std::string mSensorName;
+
+        std::mutex mLock;
+        std::mutex mRunLock;
+        bool mRunState;
+    };
+    // implement BaseDynamicSensorDaemon function
+    virtual BaseSensorVector createSensor(const std::string &deviceKey) override;
+
+    sp<ConnectionDetector> mFileDetector;
+    sp<ConnectionDetector> mSocketDetector;
+};
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_DAEMON_H
+
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
new file mode 100644
index 0000000..b634052
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BaseDynamicSensorDaemon.h"
+#include "BaseSensorObject.h"
+#include "DummyDynamicAccelDaemon.h"
+#include "HidRawSensorDaemon.h"
+#include "DynamicSensorManager.h"
+
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+#include <cassert>
+
+namespace android {
+namespace SensorHalExt {
+
+DynamicSensorManager* DynamicSensorManager::createInstance(
+        int handleBase, int handleCount, SensorEventCallback *callback) {
+    auto m = new DynamicSensorManager(handleBase, handleBase + handleCount - 1, callback);
+    m->mDaemonVector.push_back(new DummyDynamicAccelDaemon(*m));
+    m->mDaemonVector.push_back(new HidRawSensorDaemon(*m));
+    return m;
+}
+
+DynamicSensorManager::DynamicSensorManager(
+        int handleBase, int handleMax, SensorEventCallback* callback) :
+        mHandleRange(handleBase, handleMax),
+        mCallback(callback),
+        mFifo(callback ? 0 : kFifoSize),
+        mNextHandle(handleBase+1) {
+    assert(handleBase > 0 && handleMax > handleBase + 1); // handleBase is reserved
+
+    mMetaSensor = (const sensor_t) {
+        "Dynamic Sensor Manager",
+        "Google",
+        1,                                          // version
+        handleBase,                                 // handle
+        SENSOR_TYPE_DYNAMIC_SENSOR_META,
+        1,                                          // maxRange
+        1,                                          // resolution
+        1e-6f,                                      // power, very small number instead of 0
+                                                    // to avoid sigularity in app
+        (int32_t)(1000),                            // minDelay
+        0,                                          // fifoReservedEventCount
+        0,                                          // fifoMaxEventCount
+        SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META,
+        "",                                         // requiredPermission
+        (long)(1000),                               // maxDelay
+        SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP,
+        { NULL, NULL }
+    };
+}
+
+DynamicSensorManager::~DynamicSensorManager() {
+    // free all daemons first
+    mDaemonVector.clear();
+}
+
+bool DynamicSensorManager::owns(int handle) const {
+    return handle >= mHandleRange.first && handle < mHandleRange.second;
+}
+
+int DynamicSensorManager::activate(int handle, bool enable) {
+    if (handle == mHandleRange.first) {
+        // ignored
+        return 0;
+    }
+
+    // in case there is a pending report, now it is time to remove it as it is no longer necessary.
+    {
+        std::lock_guard<std::mutex> lk(mLock);
+        mPendingReport.erase(handle);
+    }
+
+    return operateSensor(handle,
+            [&enable] (sp<BaseSensorObject> s)->int {
+                return s->enable(enable);
+            });
+}
+
+int DynamicSensorManager::batch(int handle, nsecs_t sample_period, nsecs_t batch_period) {
+    if (handle == mHandleRange.first) {
+        // ignored
+        return 0;
+    }
+    return operateSensor(handle,
+            [&sample_period, &batch_period] (sp<BaseSensorObject> s)->int {
+                return s->batch(sample_period, batch_period);
+            });
+}
+
+int DynamicSensorManager::setDelay(int handle, nsecs_t sample_period) {
+    return batch(handle, sample_period, 0);
+}
+
+int DynamicSensorManager::flush(int handle) {
+    if (handle == mHandleRange.first) {
+        // submit a flush complete here
+        static const sensors_event_t event = {
+            .type = SENSOR_TYPE_META_DATA,
+            .sensor = mHandleRange.first,
+            .timestamp = TIMESTAMP_AUTO_FILL,  // timestamp will be filled at dispatcher
+        };
+        submitEvent(nullptr, event);
+        return 0;
+    }
+    return operateSensor(handle, [] (sp<BaseSensorObject> s)->int {return s->flush();});
+}
+
+int DynamicSensorManager::poll(sensors_event_t * data, int count) {
+    assert(mCallback == nullptr);
+    std::lock_guard<std::mutex> lk(mFifoLock);
+    return mFifo.read(data, count);
+}
+
+bool DynamicSensorManager::registerSensor(sp<BaseSensorObject> sensor) {
+    std::lock_guard<std::mutex> lk(mLock);
+    if (mReverseMap.find(sensor.get()) != mReverseMap.end()) {
+        ALOGE("trying to add the same sensor twice, ignore");
+        return false;
+    }
+    int handle = getNextAvailableHandle();
+    if (handle < 0) {
+        ALOGE("Running out of handle, quit.");
+        return false;
+    }
+
+    // these emplace will always be successful
+    mMap.emplace(handle, sensor);
+    mReverseMap.emplace(sensor.get(), handle);
+    sensor->setEventCallback(this);
+
+    auto entry = mPendingReport.emplace(
+            std::piecewise_construct,
+            std::forward_as_tuple(handle),
+            std::forward_as_tuple(handle, sensor));
+    if (entry.second) {
+        submitEvent(nullptr, entry.first->second.generateConnectionEvent(mHandleRange.first));
+    }
+    return entry.second;
+}
+
+void DynamicSensorManager::unregisterSensor(sp<BaseSensorObject> sensor) {
+    std::lock_guard<std::mutex> lk(mLock);
+    auto i = mReverseMap.find(sensor.get());
+    if (i == mReverseMap.end()) {
+        ALOGE("cannot remove a non-exist sensor");
+        return;
+    }
+    int handle = i->second;
+    mReverseMap.erase(i);
+    mMap.erase(handle);
+
+    // will not clean up mPendingReport here, it will be cleaned up when at first activate call.
+    // sensorservice is guranteed to call activate upon arrival of dynamic sensor meta connection
+    // event.
+
+    // send disconnection event
+    sensors_event_t event;
+    ConnectionReport::fillDisconnectionEvent(&event, mHandleRange.first, handle);
+    submitEvent(nullptr, event);
+}
+
+int DynamicSensorManager::submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) {
+    int handle;
+    if (source == nullptr) {
+        handle = mHandleRange.first;
+    } else {
+        std::lock_guard<std::mutex> lk(mLock);
+        auto i = mReverseMap.find(source.get());
+        if (i == mReverseMap.end()) {
+            ALOGE("cannot submit event for sensor that has not been registered");
+            return NAME_NOT_FOUND;
+        }
+        handle = i->second;
+    }
+
+    // making a copy of events, prepare for editing
+    sensors_event_t event = e;
+    event.version = sizeof(event);
+
+    // special case of flush complete
+    if (event.type == SENSOR_TYPE_META_DATA) {
+        event.sensor = 0;
+        event.meta_data.sensor = handle;
+    } else {
+        event.sensor = handle;
+    }
+
+    // set timestamp if it is default value
+    if (event.timestamp == TIMESTAMP_AUTO_FILL) {
+        event.timestamp = elapsedRealtimeNano();
+    }
+
+    if (mCallback) {
+        // extention mode, calling callback directly
+        int ret;
+
+        ret = mCallback->submitEvent(nullptr, event);
+        if (ret < 0) {
+            ALOGE("DynamicSensorManager callback failed, ret: %d", ret);
+        }
+    } else {
+        // standalone mode, add event to internal buffer for poll() to pick up
+        std::lock_guard<std::mutex> lk(mFifoLock);
+        if (mFifo.write(&event, 1) < 0) {
+            ALOGE("DynamicSensorManager fifo full");
+        }
+    }
+    return 0;
+}
+
+int DynamicSensorManager::getNextAvailableHandle() {
+    if (mNextHandle == mHandleRange.second) {
+        return -1;
+    }
+    return mNextHandle++;
+}
+
+const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
+    return mMetaSensor;
+}
+
+DynamicSensorManager::ConnectionReport::ConnectionReport(
+        int handle, sp<BaseSensorObject> sensor) :
+        mSensor(*(sensor->getSensor())),
+        mName(mSensor.name),
+        mVendor(mSensor.vendor),
+        mPermission(mSensor.requiredPermission),
+        mStringType(mSensor.stringType),
+        mGenerated(false) {
+    mSensor.name = mName.c_str();
+    mSensor.vendor = mVendor.c_str();
+    mSensor.requiredPermission = mPermission.c_str();
+    mSensor.stringType = mStringType.c_str();
+    mSensor.handle = handle;
+    memset(&mEvent, 0, sizeof(mEvent));
+    mEvent.version = sizeof(mEvent);
+    sensor->getUuid(mUuid);
+    ALOGV("Connection report init: name = %s, handle = %d", mSensor.name, mSensor.handle);
+}
+
+DynamicSensorManager::ConnectionReport::~ConnectionReport() {
+    ALOGV("Connection report dtor: name = %s, handle = %d", mSensor.name, mSensor.handle);
+}
+
+const sensors_event_t& DynamicSensorManager::ConnectionReport::
+        generateConnectionEvent(int metaHandle) {
+    if (!mGenerated) {
+        mEvent.sensor = metaHandle;
+        mEvent.type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
+        mEvent.timestamp = elapsedRealtimeNano();
+        mEvent.dynamic_sensor_meta =
+                (dynamic_sensor_meta_event_t) {true, mSensor.handle, &mSensor, {0}};
+        memcpy(&mEvent.dynamic_sensor_meta.uuid, &mUuid, sizeof(mEvent.dynamic_sensor_meta.uuid));
+        mGenerated = true;
+    }
+    return mEvent;
+}
+
+void DynamicSensorManager::ConnectionReport::
+        fillDisconnectionEvent(sensors_event_t* event, int metaHandle, int handle) {
+    memset(event, 0, sizeof(sensors_event_t));
+    event->version = sizeof(sensors_event_t);
+    event->sensor = metaHandle;
+    event->type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
+    event->timestamp = elapsedRealtimeNano();
+    event->dynamic_sensor_meta.connected = false;
+    event->dynamic_sensor_meta.handle = handle;
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
new file mode 100644
index 0000000..b6f39da
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H
+#define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H
+
+#include "SensorEventCallback.h"
+#include "RingBuffer.h"
+#include <hardware/sensors.h>
+#include <utils/RefBase.h>
+
+#include <mutex>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace android {
+namespace SensorHalExt {
+
+class BaseDynamicSensorDaemon;
+
+class DynamicSensorManager : public SensorEventCallback {
+public:
+    // handleBase is reserved for the dynamic sensor meta sensor.
+    // handleMax must be greater than handleBase + 1.
+    // This class has two operation mode depending on callback: 1) extension, 2) stand-alone.
+    // In extension mode, callback must not be nullptr. Sensor event generated will be submitted to
+    // buffer of primary sensor HAL implementation. In stand-alone mode, callback must be nullptr.
+    // Generated sensor events will be added into internal buffer waiting for poll() function to
+    // pick up.
+    //
+    static DynamicSensorManager* createInstance(
+            int handleBase, int handleCount, SensorEventCallback *callback);
+    virtual ~DynamicSensorManager();
+
+    // calls to add or remove sensor, called from sensor daemon
+    bool registerSensor(sp<BaseSensorObject> sensor);
+    void unregisterSensor(sp<BaseSensorObject> sensor);
+
+    // Determine if a sensor handle is in the range defined in constructor.
+    // It does not test if sensor handle is valid.
+    bool owns(int handle) const;
+
+    // handles sensor hal requests.
+    int activate(int handle, bool enable);
+    int batch(int handle, nsecs_t sample_period, nsecs_t batch_period);
+    int setDelay(int handle, nsecs_t sample_period);
+    int flush(int handle);
+    int poll(sensors_event_t * data, int count);
+
+    // SensorEventCallback
+    virtual int submitEvent(sp<BaseSensorObject>, const sensors_event_t &e) override;
+
+    // get meta sensor struct
+    const sensor_t& getDynamicMetaSensor() const;
+protected:
+    DynamicSensorManager(int handleBase, int handleMax, SensorEventCallback* callback);
+private:
+    // a helper class used for generate connection and disconnection report
+    class ConnectionReport {
+    public:
+        ConnectionReport() {}
+        ConnectionReport(int handle, sp<BaseSensorObject> sensor);
+        ~ConnectionReport();
+        const sensors_event_t& generateConnectionEvent(int metaHandle);
+        static void fillDisconnectionEvent(sensors_event_t* event, int metaHandle, int handle);
+    private:
+        sensor_t mSensor;
+        std::string mName;
+        std::string mVendor;
+        std::string mPermission;
+        std::string mStringType;
+        sensors_event_t mEvent;
+        uint8_t mUuid[16];
+        bool mGenerated;
+        DISALLOW_EVIL_CONSTRUCTORS(ConnectionReport);
+    };
+
+    // returns next available handle to use upon a new sensor connection, or -1 if we run out.
+    int getNextAvailableHandle();
+
+    // TF:  int foo(sp<BaseSensorObject> obj);
+    template <typename TF>
+    int operateSensor(int handle, TF f) const {
+        std::lock_guard<std::mutex> lk(mLock);
+        const auto i = mMap.find(handle);
+        if (i == mMap.end()) {
+            return BAD_VALUE;
+        }
+        sp<BaseSensorObject> s = i->second.promote();
+        if (s == nullptr) {
+            // sensor object is already gone
+            return BAD_VALUE;
+        }
+        return f(s);
+    }
+
+    // available sensor handle space
+    const std::pair<int, int> mHandleRange;
+    sensor_t mMetaSensor;
+
+    // immutable pointer to event callback, used in extention mode.
+    SensorEventCallback * const mCallback;
+
+    // RingBuffer used in standalone mode
+    static constexpr size_t kFifoSize = 4096; //4K events
+    mutable std::mutex mFifoLock;
+    RingBuffer mFifo;
+
+    // mapping between handle and SensorObjects
+    mutable std::mutex mLock;
+    int mNextHandle;
+    std::unordered_map<int, wp<BaseSensorObject>> mMap;
+    std::unordered_map<void *, int> mReverseMap;
+    mutable std::unordered_map<int, ConnectionReport> mPendingReport;
+
+    // daemons
+    std::vector<sp<BaseDynamicSensorDaemon>> mDaemonVector;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H
diff --git a/modules/sensors/dynamic_sensor/HidDevice.h b/modules/sensors/dynamic_sensor/HidDevice.h
new file mode 100644
index 0000000..7083593
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidDevice.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_HID_DEVICE_H
+#define ANDROID_SENSORHAL_EXT_HID_DEVICE_H
+#include "Utils.h"
+#include <string>
+#include <vector>
+#include <unordered_set>
+
+namespace android {
+namespace SensorHalExt {
+
+class HidDevice : virtual public REF_BASE(HidDevice) {
+public:
+    virtual ~HidDevice() = default;
+
+    struct HidDeviceInfo {
+        std::string name;
+        std::string physicalPath;
+        std::string busType;
+        uint16_t vendorId;
+        uint16_t productId;
+        std::vector<uint8_t> descriptor;
+    };
+
+    virtual const HidDeviceInfo& getDeviceInfo() = 0;
+
+    // get feature from device
+    virtual bool getFeature(uint8_t id, std::vector<uint8_t> *out) = 0;
+
+    // write feature to device
+    virtual bool setFeature(uint8_t id, const std::vector<uint8_t> &in) = 0;
+
+    // send report to default output endpoint
+    virtual bool sendReport(uint8_t id, std::vector<uint8_t> &data) = 0;
+
+    // receive from default input endpoint
+    virtual bool receiveReport(uint8_t *id, std::vector<uint8_t> *data) = 0;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+#endif // ANDROID_SENSORHAL_EXT_HID_DEVICE_H
diff --git a/modules/sensors/dynamic_sensor/HidRawDevice.cpp b/modules/sensors/dynamic_sensor/HidRawDevice.cpp
new file mode 100644
index 0000000..2588483
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawDevice.cpp
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidRawDevice.h"
+#include "HidLog.h"
+#include "Utils.h"
+
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+#include <linux/hiddev.h>  // HID_STRING_SIZE
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <set>
+
+namespace android {
+namespace SensorHalExt {
+
+using HidUtil::HidItem;
+
+HidRawDevice::HidRawDevice(
+        const std::string &devName, const std::unordered_set<unsigned int> &usageSet)
+        : mDevFd(-1), mMultiIdDevice(false), mValid(false) {
+    // open device
+    mDevFd = ::open(devName.c_str(), O_RDWR); // read write?
+    if (mDevFd < 0) {
+        LOG_E << "Error in open device node: " << errno << " (" << ::strerror(errno) << ")"
+              << LOG_ENDL;
+        return;
+    }
+
+    // get device information, including hid descriptor
+    if (!populateDeviceInfo()) {
+        LOG_E << "Error obtaining HidRaw device information" << LOG_ENDL;
+        return;
+    }
+
+    if (!generateDigest(usageSet)) {
+        LOG_E << "Cannot parse hid descriptor" << LOG_ENDL;
+        return;
+    }
+
+    // digest error checking
+    std::unordered_set<unsigned int> reportIdSet;
+    for (auto const &digest : mDigestVector) {
+        for (auto const &packet : digest.packets) {
+            if (mReportTypeIdMap.emplace(
+                        std::make_pair(packet.type, packet.id), &packet).second == false) {
+                LOG_E << "Same type - report id pair (" << packet.type << ", " << packet.id << ")"
+                      << "is used by more than one usage collection" << LOG_ENDL;
+                return;
+            }
+            reportIdSet.insert(packet.id);
+        }
+    }
+    if (mReportTypeIdMap.empty()) {
+        return;
+    }
+
+    if (reportIdSet.size() > 1) {
+        if (reportIdSet.find(0) != reportIdSet.end()) {
+            LOG_E << "Default report id 0 is not expected when more than one report id is found."
+                  << LOG_ENDL;
+            return;
+        }
+        mMultiIdDevice = true;
+    } else { // reportIdSet.size() == 1
+        mMultiIdDevice = !(reportIdSet.find(0) != reportIdSet.end());
+    }
+    mValid = true;
+}
+
+HidRawDevice::~HidRawDevice() {
+    if (mDevFd > 0) {
+        ::close(mDevFd);
+        mDevFd = -1;
+    }
+}
+
+bool HidRawDevice::populateDeviceInfo() {
+    HidDeviceInfo info;
+    char buffer[HID_STRING_SIZE + 1];
+
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    // name
+    if (ioctl(mDevFd, HIDIOCGRAWNAME(sizeof(buffer) - 1), buffer) < 0) {
+        return false;
+    }
+    buffer[sizeof(buffer) - 1] = '\0';
+    info.name = buffer;
+
+    // physical path
+    if (ioctl(mDevFd, HIDIOCGRAWPHYS(sizeof(buffer) - 1), buffer) < 0) {
+        return false;
+    }
+    buffer[sizeof(buffer) - 1] = '\0';
+    info.physicalPath = buffer;
+
+    // raw device info
+    hidraw_devinfo devInfo;
+    if (ioctl(mDevFd, HIDIOCGRAWINFO, &devInfo) < 0) {
+        return false;
+    }
+
+    switch (devInfo.bustype) {
+    case BUS_USB:
+        info.busType = "USB";
+        break;
+    case BUS_HIL:
+        info.busType = "HIL";
+        break;
+    case BUS_BLUETOOTH:
+        info.busType = "Bluetooth";
+        break;
+    case BUS_VIRTUAL:
+        info.busType = "Virtual";
+        break;
+    default:
+        info.busType = "Other";
+        break;
+    }
+
+    info.vendorId = devInfo.vendor;
+    info.productId = devInfo.vendor;
+
+    uint32_t descriptorSize;
+    /* Get Report Descriptor Size */
+    if (ioctl(mDevFd, HIDIOCGRDESCSIZE, &descriptorSize) < 0) {
+        return false;
+    }
+
+    struct hidraw_report_descriptor reportDescriptor;
+    memset(&reportDescriptor, 0, sizeof(reportDescriptor));
+    info.descriptor.resize(descriptorSize);
+    reportDescriptor.size = descriptorSize;
+    if (ioctl(mDevFd, HIDIOCGRDESC, &reportDescriptor) < 0) {
+        return false;
+    }
+    std::copy(reportDescriptor.value, reportDescriptor.value + descriptorSize,
+              info.descriptor.begin());
+    mDeviceInfo = info;
+    return true;
+}
+
+bool HidRawDevice::generateDigest(const std::unordered_set<unsigned int> &usage) {
+    if (mDeviceInfo.descriptor.empty()) {
+        return false;
+    }
+
+    std::vector<HidItem> tokens = HidItem::tokenize(mDeviceInfo.descriptor);
+    HidParser parser;
+    if (!parser.parse(tokens)) {
+        return false;
+    }
+
+    parser.filterTree();
+    mDigestVector = parser.generateDigest(usage);
+
+    return mDigestVector.size() > 0;
+}
+
+bool HidRawDevice::isValid() {
+    return mValid;
+}
+
+bool HidRawDevice::getFeature(uint8_t id, std::vector<uint8_t> *out) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    if (out == nullptr) {
+        return false;
+    }
+
+    const HidParser::ReportPacket *packet = getReportPacket(HidParser::REPORT_TYPE_FEATURE, id);
+    if (packet == nullptr) {
+        LOG_E << "HidRawDevice::getFeature: unknown feature " << id << LOG_ENDL;
+        return false;
+    }
+
+    size_t size = packet->getByteSize() + 1; // report id size
+
+    std::lock_guard<std::mutex> l(mIoBufferLock);
+    if (mIoBuffer.size() < size) {
+        mIoBuffer.resize(size);
+    }
+    mIoBuffer[0] = id;
+    int res = ::ioctl(mDevFd, HIDIOCGFEATURE(size), mIoBuffer.data());
+    if (res < 0) {
+        LOG_E << "HidRawDevice::getFeature: feature " << static_cast<int>(id)
+              << " ioctl returns " << res << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+
+    if (static_cast<size_t>(res) != size) {
+        LOG_E << "HidRawDevice::getFeature: get feature " << static_cast<int>(id)
+              << " returned " << res << " bytes, does not match expected " << size << LOG_ENDL;
+        return false;
+    }
+    if (mIoBuffer.front() != id) {
+        LOG_E << "HidRawDevice::getFeature: get feature " << static_cast<int>(id)
+              << " result has header " << mIoBuffer.front() << LOG_ENDL;
+    }
+    out->resize(size - 1);
+    std::copy(mIoBuffer.begin() + 1, mIoBuffer.begin() + size, out->begin());
+    return true;
+}
+
+bool HidRawDevice::setFeature(uint8_t id, const std::vector<uint8_t> &in) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    const HidParser::ReportPacket *packet = getReportPacket(HidParser::REPORT_TYPE_FEATURE, id);
+    if (packet == nullptr) {
+        LOG_E << "HidRawDevice::setFeature: Unknown feature " << id << LOG_ENDL;
+        return false;
+    }
+
+    size_t size = packet->getByteSize();
+    if (size != in.size()) {
+        LOG_E << "HidRawDevice::setFeature: set feature " << id << " size mismatch, need "
+              << size << " bytes, have " << in.size() << " bytes" << LOG_ENDL;
+        return false;
+    }
+
+    ++size; // report id byte
+    std::lock_guard<std::mutex> l(mIoBufferLock);
+    if (mIoBuffer.size() < size) {
+        mIoBuffer.resize(size);
+    }
+    mIoBuffer[0] = id;
+    std::copy(in.begin(), in.end(), &mIoBuffer[1]);
+    int res = ::ioctl(mDevFd, HIDIOCSFEATURE(size), mIoBuffer.data());
+    if (res < 0) {
+        LOG_E << "HidRawDevice::setFeature: feature " << id << " ioctl returns " << res
+              << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+    return true;
+}
+
+bool HidRawDevice::sendReport(uint8_t id, std::vector<uint8_t> &data) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    const HidParser::ReportPacket *packet = getReportPacket(HidParser::REPORT_TYPE_OUTPUT, id);
+    if (packet == nullptr) {
+        LOG_E << "HidRawDevice::sendReport: unknown output " << id << LOG_ENDL;
+        return false;
+    }
+
+    size_t size = packet->getByteSize();
+    if (size != data.size()) {
+        LOG_E << "HidRawDevice::sendReport: send report " << id << " size mismatch, need "
+              << size << " bytes, have " << data.size() << " bytes" << LOG_ENDL;
+        return false;
+    }
+    int res;
+    if (mMultiIdDevice) {
+        std::lock_guard<std::mutex> l(mIoBufferLock);
+        ++size;
+        if (mIoBuffer.size() < size) {
+            mIoBuffer.resize(size);
+        }
+        mIoBuffer[0] = id;
+        std::copy(mIoBuffer.begin() + 1, mIoBuffer.end(), data.begin());
+        res = ::write(mDevFd, mIoBuffer.data(), size);
+    } else {
+        res = ::write(mDevFd, data.data(), size);
+    }
+    if (res < 0) {
+        LOG_E << "HidRawDevice::sendReport: output " << id << " write returns " << res
+              << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+    return true;
+}
+
+bool HidRawDevice::receiveReport(uint8_t *id, std::vector<uint8_t> *data) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    uint8_t buffer[256];
+    int res = ::read(mDevFd, buffer, 256);
+    if (res < 0) {
+        LOG_E << "HidRawDevice::receiveReport: read returns " << res
+              << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+
+    if (mMultiIdDevice) {
+        if (!(res > 1)) {
+            LOG_E << "read hidraw returns data too short, len: " << res << LOG_ENDL;
+            return false;
+        }
+        data->resize(static_cast<size_t>(res - 1));
+        std::copy(buffer + 1, buffer + res, data->begin());
+        *id = buffer[0];
+    } else {
+        data->resize(static_cast<size_t>(res));
+        std::copy(buffer, buffer + res, data->begin());
+        *id = 0;
+    }
+    return true;
+}
+
+const HidParser::ReportPacket *HidRawDevice::getReportPacket(unsigned int type, unsigned int id) {
+    auto i = mReportTypeIdMap.find(std::make_pair(type, id));
+    return (i == mReportTypeIdMap.end()) ? nullptr : i->second;
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/HidRawDevice.h b/modules/sensors/dynamic_sensor/HidRawDevice.h
new file mode 100644
index 0000000..707dfff
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawDevice.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+
+#include "HidDevice.h"
+
+#include <HidParser.h>
+#include <string>
+#include <vector>
+#include <unordered_set>
+#include <unordered_map>
+
+namespace android {
+namespace SensorHalExt {
+
+using HidUtil::HidParser;
+using HidUtil::HidReport;
+
+class HidRawDevice : public HidDevice {
+    friend class HidRawDeviceTest;
+public:
+    HidRawDevice(const std::string &devName, const std::unordered_set<unsigned int> &usageSet);
+    virtual ~HidRawDevice();
+
+    // test if the device initialized successfully
+    bool isValid();
+
+    // implement HidDevice pure virtuals
+    virtual HidDeviceInfo& getDeviceInfo() override { return mDeviceInfo; }
+    virtual bool getFeature(uint8_t id, std::vector<uint8_t> *out) override;
+    virtual bool setFeature(uint8_t id, const std::vector<uint8_t> &in) override;
+    virtual bool sendReport(uint8_t id, std::vector<uint8_t> &data) override;
+    virtual bool receiveReport(uint8_t *id, std::vector<uint8_t> *data) override;
+
+protected:
+    bool populateDeviceInfo();
+    size_t getReportSize(int type, uint8_t id);
+    bool generateDigest(const std::unordered_set<uint32_t> &usage);
+    size_t calculateReportBitSize(const std::vector<HidReport> &reportItems);
+    const HidParser::ReportPacket *getReportPacket(unsigned int type, unsigned int id);
+
+    typedef std::pair<unsigned int, unsigned int> ReportTypeIdPair;
+    struct UnsignedIntPairHash {
+        size_t operator()(const ReportTypeIdPair& v) const {
+            std::hash<unsigned int> hash;
+            return hash(v.first) ^ hash(v.second);
+        }
+    };
+
+    std::unordered_map<ReportTypeIdPair, const HidParser::ReportPacket *, UnsignedIntPairHash>
+            mReportTypeIdMap;
+
+    HidParser::DigestVector mDigestVector;
+private:
+    std::mutex mIoBufferLock;
+    std::vector<uint8_t> mIoBuffer;
+
+    int mDevFd;
+    HidDeviceInfo mDeviceInfo;
+    bool mMultiIdDevice;
+    int mValid;
+
+    HidRawDevice(const HidRawDevice &) = delete;
+    void operator=(const HidRawDevice &) = delete;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
new file mode 100644
index 0000000..a64d7a6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
@@ -0,0 +1,1044 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidRawSensor.h"
+#include "HidSensorDef.h"
+
+#include <utils/Errors.h>
+#include "HidLog.h"
+
+#include <algorithm>
+#include <cfloat>
+#include <codecvt>
+#include <iomanip>
+#include <sstream>
+
+namespace android {
+namespace SensorHalExt {
+
+namespace {
+const std::string CUSTOM_TYPE_PREFIX("com.google.hardware.sensor.hid_dynamic.");
+}
+
+HidRawSensor::HidRawSensor(
+        SP(HidDevice) device, uint32_t usage, const std::vector<HidParser::ReportPacket> &packets)
+        : mReportingStateId(-1), mPowerStateId(-1), mReportIntervalId(-1), mInputReportId(-1),
+        mEnabled(false), mSamplingPeriod(1000ll*1000*1000), mBatchingPeriod(0),
+        mDevice(device), mValid(false) {
+    if (device == nullptr) {
+        return;
+    }
+    memset(&mSensor, 0, sizeof(mSensor));
+
+    const HidDevice::HidDeviceInfo &info =  device->getDeviceInfo();
+    initFeatureValueFromHidDeviceInfo(&mFeatureInfo, info);
+
+    if (!populateFeatureValueFromFeatureReport(&mFeatureInfo, packets)) {
+        LOG_E << "populate feature from feature report failed" << LOG_ENDL;
+        return;
+    }
+
+    if (!findSensorControlUsage(packets)) {
+        LOG_E << "finding sensor control usage failed" << LOG_ENDL;
+        return;
+    }
+
+    // build translation table
+    bool translationTableValid = false;
+    switch (usage) {
+        using namespace Hid::Sensor::SensorTypeUsage;
+        using namespace Hid::Sensor::ReportUsage;
+        case ACCELEROMETER_3D:
+            // Hid unit default g
+            // Android unit m/s^2
+            // 1g = 9.81 m/s^2
+            mFeatureInfo.typeString = SENSOR_STRING_TYPE_ACCELEROMETER;
+            mFeatureInfo.type = SENSOR_TYPE_ACCELEROMETER;
+            mFeatureInfo.isWakeUp = false;
+
+            translationTableValid = processTriAxisUsage(packets,
+                                         ACCELERATION_X_AXIS,
+                                         ACCELERATION_Y_AXIS,
+                                         ACCELERATION_Z_AXIS, 9.81);
+            break;
+        case GYROMETER_3D:
+            // Hid unit default degree/s
+            // Android unit rad/s
+            // 1 degree/s = pi/180 rad/s
+            mFeatureInfo.typeString = SENSOR_STRING_TYPE_GYROSCOPE;
+            mFeatureInfo.type = SENSOR_TYPE_GYROSCOPE;
+            mFeatureInfo.isWakeUp = false;
+
+            translationTableValid = processTriAxisUsage(packets,
+                                         ANGULAR_VELOCITY_X_AXIS,
+                                         ANGULAR_VELOCITY_Y_AXIS,
+                                         ANGULAR_VELOCITY_Z_AXIS, M_PI/180);
+            break;
+        case COMPASS_3D: {
+            // Hid unit default mGauss
+            // Android unit uT
+            // 1uT  = 0.1 nGauss
+            mFeatureInfo.typeString = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
+            mFeatureInfo.type = SENSOR_TYPE_MAGNETIC_FIELD;
+
+            if (!processTriAxisUsage(packets,
+                                     MAGNETIC_FLUX_X_AXIS,
+                                     MAGNETIC_FLUX_Y_AXIS,
+                                     MAGNETIC_FLUX_Z_AXIS, 0.1)) {
+                break;
+            }
+            const HidParser::ReportItem *pReportAccuracy = find(packets,
+                                                                  MAGNETOMETER_ACCURACY,
+                                                                  HidParser::REPORT_TYPE_INPUT,
+                                                                  mInputReportId);
+
+            if (pReportAccuracy == nullptr) {
+                LOG_E << "Cannot find accuracy field in usage "
+                      << std::hex << usage << std::dec << LOG_ENDL;
+                break;
+            }
+            if (!pReportAccuracy->isByteAligned()) {
+                LOG_E << "Accuracy field must align to byte" << LOG_ENDL;
+                break;
+            }
+            if (pReportAccuracy->minRaw != 0 || pReportAccuracy->maxRaw != 2) {
+                LOG_E << "Accuracy field value range must be [0, 2]" << LOG_ENDL;
+                break;
+            }
+            ReportTranslateRecord accuracyRecord = {
+                .type = TYPE_ACCURACY,
+                .maxValue = 2,
+                .minValue = 0,
+                .byteOffset = pReportAccuracy->bitOffset / 8,
+                .byteSize = pReportAccuracy->bitSize / 8,
+                .a = 1,
+                .b = 1};
+            mTranslateTable.push_back(accuracyRecord);
+            translationTableValid = true;
+            break;
+        }
+        case DEVICE_ORIENTATION:
+            translationTableValid = processQuaternionUsage(packets);
+            break;
+        case CUSTOM: {
+            if (!mFeatureInfo.isAndroidCustom) {
+                LOG_E << "Invalid android custom sensor" << LOG_ENDL;
+                break;
+            }
+            const HidParser::ReportPacket *pPacket = nullptr;
+            const uint32_t usages[] = {
+                CUSTOM_VALUE_1, CUSTOM_VALUE_2, CUSTOM_VALUE_3,
+                CUSTOM_VALUE_4, CUSTOM_VALUE_5, CUSTOM_VALUE_6
+            };
+            for (const auto &packet : packets) {
+                if (packet.type == HidParser::REPORT_TYPE_INPUT && std::any_of(
+                        packet.reports.begin(), packet.reports.end(),
+                        [&usages] (const HidParser::ReportItem &d) {
+                               return std::find(std::begin(usages), std::end(usages), d.usage)
+                                       != std::end(usages);
+                        })) {
+                    pPacket = &packet;
+                    break;
+                }
+            }
+
+            if (pPacket == nullptr) {
+                LOG_E << "Cannot find CUSTOM_VALUE_X in custom sensor" << LOG_ENDL;
+                break;
+            }
+
+            double range = 0;
+            double resolution = 1;
+
+            for (const auto &digest : pPacket->reports) {
+                if (digest.minRaw >= digest.maxRaw) {
+                    LOG_E << "Custome usage " << digest.usage << ", min must < max" << LOG_ENDL;
+                    return;
+                }
+
+                if (!digest.isByteAligned()
+                        || (digest.bitSize != 8 && digest.bitSize != 16 && digest.bitSize != 32)) {
+                    LOG_E << "Custome usage " << std::hex << digest.usage << std::hex
+                          << ", each input must be 8/16/32 bits and must align to byte boundary"
+                          << LOG_ENDL;
+                    return;
+                }
+
+                ReportTranslateRecord record = {
+                    .minValue = digest.minRaw,
+                    .maxValue = digest.maxRaw,
+                    .byteOffset = digest.bitOffset / 8,
+                    .byteSize = digest.bitSize / 8,
+                    .a = digest.a,
+                    .b = digest.b,
+                    .type = TYPE_FLOAT
+                };
+                // keep track of range and resolution
+                range = std::max(std::max(std::abs((digest.maxRaw + digest.b) * digest.a),
+                                          std::abs((digest.minRaw + digest.b) * digest.a)),
+                                 range);
+                resolution = std::min(digest.a, resolution);
+
+                for (size_t i = 0; i < digest.count; ++i) {
+                    if (mTranslateTable.size() == 16) {
+                        LOG_I << "Custom usage has more than 16 inputs, ignore the rest" << LOG_ENDL;
+                        break;
+                    }
+                    record.index = mTranslateTable.size();
+                    mTranslateTable.push_back(record);
+                    record.byteOffset += digest.bitSize / 8;
+                }
+                if (mTranslateTable.size() == 16) {
+                    break;
+                }
+            }
+            mFeatureInfo.maxRange = range;
+            mFeatureInfo.resolution = resolution;
+            mInputReportId = pPacket->id;
+            translationTableValid = !mTranslateTable.empty();
+            break;
+        }
+        default:
+            LOG_I << "unsupported sensor usage " << usage << LOG_ENDL;
+    }
+
+    bool sensorValid = validateFeatureValueAndBuildSensor();
+    mValid = translationTableValid && sensorValid;
+    LOG_V << "HidRawSensor init, translationTableValid: " << translationTableValid
+          << ", sensorValid: " << sensorValid << LOG_ENDL;
+}
+
+bool HidRawSensor::processQuaternionUsage(const std::vector<HidParser::ReportPacket> &packets) {
+    const HidParser::ReportItem *pReportQuaternion
+            = find(packets,
+                   Hid::Sensor::ReportUsage::ORIENTATION_QUATERNION,
+                   HidParser::REPORT_TYPE_INPUT);
+
+    if (pReportQuaternion == nullptr) {
+        return false;
+    }
+
+    const HidParser::ReportItem &quat = *pReportQuaternion;
+    if ((quat.bitSize != 16 && quat.bitSize != 32) || !quat.isByteAligned()) {
+        LOG_E << "Quaternion usage input must be 16 or 32 bits and aligned at byte boundary" << LOG_ENDL;
+        return false;
+    }
+
+    double min, max;
+    quat.decode(quat.mask(quat.minRaw), &min);
+    quat.decode(quat.mask(quat.maxRaw), &max);
+    if (quat.count != 4 || min > -1 || max < 1) {
+        LOG_E << "Quaternion usage need 4 inputs with range [-1, 1]" << LOG_ENDL;
+        return false;
+    }
+
+    if (quat.minRaw > quat.maxRaw) {
+        LOG_E << "Quaternion usage min must <= max" << LOG_ENDL;
+        return false;
+    }
+
+    ReportTranslateRecord record = {
+        .minValue = quat.minRaw,
+        .maxValue = quat.maxRaw,
+        .byteOffset = quat.bitOffset / 8,
+        .byteSize = quat.bitSize / 8,
+        .b = quat.b,
+        .type = TYPE_FLOAT,
+    };
+
+    // Android X Y Z maps to HID X -Z Y
+    // Android order xyzw, HID order wxyz
+    // X
+    record.index = 0;
+    record.a = quat.a;
+    record.byteOffset = (quat.bitOffset + quat.bitSize) / 8;
+    mTranslateTable.push_back(record);
+    // Y
+    record.index = 1;
+    record.a = -quat.a;
+    record.byteOffset = (quat.bitOffset + 3 * quat.bitSize) / 8;
+    mTranslateTable.push_back(record);
+    // Z
+    record.index = 2;
+    record.a = quat.a;
+    record.byteOffset = (quat.bitOffset + 2 * quat.bitSize) / 8;
+    mTranslateTable.push_back(record);
+    // W
+    record.index = 3;
+    record.a = quat.a;
+    record.byteOffset = quat.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    mFeatureInfo.typeString = SENSOR_STRING_TYPE_ROTATION_VECTOR;
+    mFeatureInfo.type = SENSOR_TYPE_ROTATION_VECTOR;
+    mFeatureInfo.maxRange = 1;
+    mFeatureInfo.resolution = quat.a;
+    mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
+
+    mInputReportId = quat.id;
+
+    return true;
+}
+
+bool HidRawSensor::processTriAxisUsage(const std::vector<HidParser::ReportPacket> &packets,
+        uint32_t usageX, uint32_t usageY, uint32_t usageZ, double defaultScaling) {
+    const HidParser::ReportItem *pReportX = find(packets, usageX, HidParser::REPORT_TYPE_INPUT);
+    const HidParser::ReportItem *pReportY = find(packets, usageY, HidParser::REPORT_TYPE_INPUT);
+    const HidParser::ReportItem *pReportZ = find(packets, usageZ, HidParser::REPORT_TYPE_INPUT);
+
+    if (pReportX == nullptr || pReportY == nullptr|| pReportZ == nullptr) {
+        LOG_E << "Three axis sensor does not find all 3 axis" << LOG_ENDL;
+        return false;
+    }
+
+    const HidParser::ReportItem &reportX = *pReportX;
+    const HidParser::ReportItem &reportY = *pReportY;
+    const HidParser::ReportItem &reportZ = *pReportZ;
+    if (reportX.id != reportY.id || reportY.id != reportZ.id) {
+        LOG_E << "All 3 axis should be in the same report" << LOG_ENDL;
+        return false;
+    }
+    if (reportX.minRaw >= reportX.maxRaw
+            || reportX.minRaw != reportY.minRaw
+            || reportX.maxRaw != reportY.maxRaw
+            || reportY.minRaw != reportZ.minRaw
+            || reportY.maxRaw != reportZ.maxRaw) {
+        LOG_E << "All 3 axis should have same min and max value and min must < max" << LOG_ENDL;
+        return false;
+    }
+    if (reportX.a != reportY.a || reportY.a != reportY.a) {
+        LOG_E << "All 3 axis should have same resolution" << LOG_ENDL;
+        return false;
+    }
+    if (reportX.count != 1 || reportY.count != 1 || reportZ.count != 1
+            || (reportX.bitSize != 16 && reportX.bitSize != 32)
+            || reportX.bitSize != reportY.bitSize || reportY.bitSize != reportZ.bitSize
+            || !reportX.isByteAligned()
+            || !reportY.isByteAligned()
+            || !reportZ.isByteAligned() ) {
+        LOG_E << "All 3 axis should have count == 1, same size == 16 or 32 "
+              "and align at byte boundary" << LOG_ENDL;
+        return false;
+    }
+
+    if (reportX.unit != 0 || reportY.unit != 0 || reportZ.unit != 0) {
+        LOG_E << "Specified unit for usage is not supported" << LOG_ENDL;
+        return false;
+    }
+
+    if (reportX.a != reportY.a || reportY.a != reportZ.a
+        || reportX.b != reportY.b || reportY.b != reportZ.b) {
+        LOG_W << "Scaling for 3 axis are different. It is recommended to keep them the same" << LOG_ENDL;
+    }
+
+    // set features
+    mFeatureInfo.maxRange = std::max(
+        std::abs((reportX.maxRaw + reportX.b) * reportX.a),
+        std::abs((reportX.minRaw + reportX.b) * reportX.a));
+    mFeatureInfo.resolution = reportX.a * defaultScaling;
+    mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
+
+    ReportTranslateRecord record = {
+        .minValue = reportX.minRaw,
+        .maxValue = reportX.maxRaw,
+        .byteSize = reportX.bitSize / 8,
+        .type = TYPE_FLOAT
+    };
+
+    // Reorder and swap axis
+    //
+    // HID class devices are encouraged, where possible, to use a right-handed
+    // coordinate system. If a user is facing a device, report values should increase as
+    // controls are moved from left to right (X), from far to near (Y) and from high to
+    // low (Z).
+    //
+
+    // Android X axis = Hid X axis
+    record.index = 0;
+    record.a = reportX.a * defaultScaling;
+    record.b = reportX.b;
+    record.byteOffset = reportX.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    // Android Y axis = - Hid Z axis
+    record.index = 1;
+    record.a = -reportZ.a * defaultScaling;
+    record.b = reportZ.b;
+    record.byteOffset = reportZ.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    // Android Z axis = Hid Y axis
+    record.index = 2;
+    record.a = reportY.a * defaultScaling;
+    record.b = reportY.b;
+    record.byteOffset = reportY.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    mInputReportId = reportX.id;
+    return true;
+}
+
+const HidParser::ReportItem *HidRawSensor::find(
+        const std::vector<HidParser::ReportPacket> &packets,
+        unsigned int usage, int type, int id) {
+    for (const auto &packet : packets) {
+        if (packet.type != type) {
+            continue;
+        }
+        auto i = std::find_if(
+                packet.reports.begin(), packet.reports.end(),
+                [usage, id](const HidParser::ReportItem &p) {
+                    return p.usage == usage
+                            && (id == -1 || p.id == static_cast<unsigned int>(id));
+                });
+        if (i != packet.reports.end()) {
+            return &(*i);
+        }
+    }
+    return nullptr;
+};
+
+void HidRawSensor::initFeatureValueFromHidDeviceInfo(
+        FeatureValue *featureValue, const HidDevice::HidDeviceInfo &info) {
+    featureValue->name = info.name;
+
+    std::ostringstream ss;
+    ss << info.busType << " "
+       << std::hex << std::setfill('0') << std::setw(4) << info.vendorId
+       << ":" << std::setw(4) << info.productId;
+    featureValue->vendor = ss.str();
+
+    featureValue->permission = "";
+    featureValue->typeString = "";
+    featureValue->type = -1; // invalid type
+    featureValue->version = 1;
+
+    featureValue->maxRange = -1.f;
+    featureValue->resolution = FLT_MAX;
+    featureValue->power = 1.f; // default value, does not have a valid source yet
+
+    featureValue->minDelay = 0;
+    featureValue->maxDelay = 0;
+
+    featureValue->fifoSize = 0;
+    featureValue->fifoMaxSize = 0;
+
+    featureValue->reportModeFlag = SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+    featureValue->isWakeUp = false;
+    memset(featureValue->uuid, 0, sizeof(featureValue->uuid));
+    featureValue->isAndroidCustom = false;
+}
+
+bool HidRawSensor::populateFeatureValueFromFeatureReport(
+        FeatureValue *featureValue, const std::vector<HidParser::ReportPacket> &packets) {
+    SP(HidDevice) device = PROMOTE(mDevice);
+    if (device == nullptr) {
+        return false;
+    }
+
+    std::vector<uint8_t> buffer;
+    for (const auto &packet : packets) {
+        if (packet.type != HidParser::REPORT_TYPE_FEATURE) {
+            continue;
+        }
+
+        if (!device->getFeature(packet.id, &buffer)) {
+            continue;
+        }
+
+        std::string str;
+        using namespace Hid::Sensor::PropertyUsage;
+        for (const auto & r : packet.reports) {
+            switch (r.usage) {
+                case FRIENDLY_NAME:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+                        // invalid friendly name
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str) && !str.empty()) {
+                        featureValue->name = str;
+                    }
+                    break;
+                case SENSOR_MANUFACTURER:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+                        // invalid manufacturer
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str) && !str.empty()) {
+                        featureValue->vendor = str;
+                    }
+                    break;
+                case PERSISTENT_UNIQUE_ID:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+                        // invalid unique id string
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str) && !str.empty()) {
+                        featureValue->uniqueId = str;
+                    }
+                    break;
+                case SENSOR_DESCRIPTION:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1
+                            || (r.bitOffset / 8 + r.count * 2) > buffer.size() ) {
+                        // invalid description
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str)) {
+                        mFeatureInfo.isAndroidCustom = detectAndroidCustomSensor(str);
+                    }
+                    break;
+                default:
+                    // do not care about others
+                    break;
+            }
+        }
+    }
+    return true;
+}
+
+bool HidRawSensor::validateFeatureValueAndBuildSensor() {
+    if (mFeatureInfo.name.empty() || mFeatureInfo.vendor.empty() || mFeatureInfo.typeString.empty()
+            || mFeatureInfo.type <= 0 || mFeatureInfo.maxRange <= 0
+            || mFeatureInfo.resolution <= 0) {
+        return false;
+    }
+
+    switch (mFeatureInfo.reportModeFlag) {
+        case SENSOR_FLAG_CONTINUOUS_MODE:
+        case SENSOR_FLAG_ON_CHANGE_MODE:
+            if (mFeatureInfo.minDelay < 0) {
+                return false;
+            }
+            if (mFeatureInfo.maxDelay != 0 && mFeatureInfo.maxDelay < mFeatureInfo.minDelay) {
+                return false;
+            }
+            break;
+        case SENSOR_FLAG_ONE_SHOT_MODE:
+            if (mFeatureInfo.minDelay != -1 && mFeatureInfo.maxDelay != 0) {
+                return false;
+            }
+            break;
+        case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
+            if (mFeatureInfo.minDelay != -1 && mFeatureInfo.maxDelay != 0) {
+                return false;
+            }
+            break;
+        default:
+            break;
+    }
+
+    if (mFeatureInfo.fifoMaxSize < mFeatureInfo.fifoSize) {
+        return false;
+    }
+
+    // initialize uuid field, use name, vendor and uniqueId
+    if (mFeatureInfo.name.size() >= 4
+            && mFeatureInfo.vendor.size() >= 4
+            && mFeatureInfo.typeString.size() >= 4
+            && mFeatureInfo.uniqueId.size() >= 4) {
+        uint32_t tmp[4], h;
+        std::hash<std::string> stringHash;
+        h = stringHash(mFeatureInfo.uniqueId);
+        tmp[0] = stringHash(mFeatureInfo.name) ^ h;
+        tmp[1] = stringHash(mFeatureInfo.vendor) ^ h;
+        tmp[2] = stringHash(mFeatureInfo.typeString) ^ h;
+        tmp[3] = tmp[0] ^ tmp[1] ^ tmp[2];
+        memcpy(mFeatureInfo.uuid, tmp, sizeof(mFeatureInfo.uuid));
+    }
+
+    mSensor = (sensor_t) {
+        mFeatureInfo.name.c_str(),                 // name
+        mFeatureInfo.vendor.c_str(),               // vendor
+        mFeatureInfo.version,                      // version
+        -1,                                        // handle, dummy number here
+        mFeatureInfo.type,
+        mFeatureInfo.maxRange,                     // maxRange
+        mFeatureInfo.resolution,                   // resolution
+        mFeatureInfo.power,                        // power
+        mFeatureInfo.minDelay,                     // minDelay
+        (uint32_t)mFeatureInfo.fifoSize,           // fifoReservedEventCount
+        (uint32_t)mFeatureInfo.fifoMaxSize,        // fifoMaxEventCount
+        mFeatureInfo.typeString.c_str(),           // type string
+        mFeatureInfo.permission.c_str(),           // requiredPermission
+        (long)mFeatureInfo.maxDelay,               // maxDelay
+        mFeatureInfo.reportModeFlag | (mFeatureInfo.isWakeUp ? 1 : 0),
+        { NULL, NULL }
+    };
+    return true;
+}
+
+bool HidRawSensor::decodeString(
+        const HidParser::ReportItem &report, const std::vector<uint8_t> &buffer, std::string *d) {
+    if (!report.isByteAligned() || report.bitSize != 16 || report.count < 1) {
+        return false;
+    }
+
+    size_t offset = report.bitOffset / 8;
+    if (offset + report.count * 2 > buffer.size()) {
+        return false;
+    }
+
+    std::vector<uint16_t> data(report.count);
+    auto i = data.begin();
+    auto j = buffer.begin() + offset;
+    for ( ; i != data.end(); ++i, j += sizeof(uint16_t)) {
+        // hid specified little endian
+        *i = *j + (*(j + 1) << 8);
+    }
+    std::wstring wstr(data.begin(), data.end());
+
+    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
+    *d = converter.to_bytes(wstr);
+    return true;
+}
+
+std::vector<std::string> split(const std::string &text, char sep) {
+    std::vector<std::string> tokens;
+    size_t start = 0, end = 0;
+    while ((end = text.find(sep, start)) != std::string::npos) {
+        if (end != start) {
+            tokens.push_back(text.substr(start, end - start));
+        }
+        start = end + 1;
+    }
+    if (end != start) {
+        tokens.push_back(text.substr(start));
+    }
+    return tokens;
+}
+
+bool HidRawSensor::detectAndroidCustomSensor(const std::string &description) {
+    size_t nullPosition = description.find('\0');
+    if (nullPosition == std::string::npos) {
+        return false;
+    }
+    const std::string prefix("#ANDROID#");
+    if (description.find(prefix, nullPosition + 1) != nullPosition + 1) {
+        return false;
+    }
+
+    std::string str(description.c_str() + nullPosition + 1 + prefix.size());
+
+    // Format for predefined sensor types:
+    // #ANDROID#nn,[C|X|T|S],[B|0],[W|N]
+    // Format for vendor type sensor
+    // #ANDROID#xxx.yyy.zzz,[C|X|T|S],[B|0],[W|N]
+    //
+    // C: continuous
+    // X: on-change
+    // T: one-shot
+    // S: special trigger
+    //
+    // B: body permission
+    // 0: no permission required
+    std::vector<std::string> segments;
+    size_t start = 0, end = 0;
+    while ((end = str.find(',', start)) != std::string::npos) {
+        if (end != start) {
+            segments.push_back(str.substr(start, end - start));
+        }
+        start = end + 1;
+    }
+    if (end != start) {
+        segments.push_back(str.substr(start));
+    }
+
+    if (segments.size() < 4) {
+        LOG_E << "Not enough segments in android custom description" << LOG_ENDL;
+        return false;
+    }
+
+    // type
+    bool typeParsed = false;
+    if (!segments[0].empty()) {
+        if (::isdigit(segments[0][0])) {
+            int type = ::atoi(segments[0].c_str());
+            // all supported types here
+            switch (type) {
+                case SENSOR_TYPE_HEART_RATE:
+                    mFeatureInfo.type = SENSOR_TYPE_HEART_RATE;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_HEART_RATE;
+                    typeParsed = true;
+                    break;
+                case SENSOR_TYPE_AMBIENT_TEMPERATURE:
+                    mFeatureInfo.type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
+                    typeParsed = true;
+                case SENSOR_TYPE_LIGHT:
+                    mFeatureInfo.type = SENSOR_TYPE_LIGHT;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_LIGHT;
+                    typeParsed = true;
+                    break;
+                case SENSOR_TYPE_PRESSURE:
+                    mFeatureInfo.type = SENSOR_TYPE_PRESSURE;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_PRESSURE;
+                    typeParsed = true;
+                    break;
+                default:
+                    LOG_W << "Android type " << type << " has not been supported yet" << LOG_ENDL;
+                    break;
+            }
+        } else {
+            // assume a xxx.yyy.zzz format
+            std::ostringstream s;
+            bool lastIsDot = true;
+            for (auto c : segments[0]) {
+                if (::isalpha(c)) {
+                    s << static_cast<char>(c);
+                    lastIsDot = false;
+                } else if (!lastIsDot && c == '.') {
+                    s << static_cast<char>(c);
+                    lastIsDot = true;
+                } else {
+                    break;
+                }
+            }
+            if (s.str() == segments[0]) {
+                mFeatureInfo.type = SENSOR_TYPE_DEVICE_PRIVATE_BASE;
+                mFeatureInfo.typeString = CUSTOM_TYPE_PREFIX + s.str();
+                typeParsed = true;
+            }
+        }
+    }
+
+    // reporting type
+    bool reportingModeParsed = false;
+    if (segments[1].size() == 1) {
+        switch (segments[1][0]) {
+            case 'C':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
+                reportingModeParsed = true;
+                break;
+            case 'X':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_ON_CHANGE_MODE;
+                reportingModeParsed = true;
+                break;
+            case 'T':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_ONE_SHOT_MODE;
+                reportingModeParsed = true;
+                break;
+            case 'S':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+                reportingModeParsed = true;
+                break;
+            default:
+                LOG_E << "Undefined reporting mode designation " << segments[1] << LOG_ENDL;
+        }
+    }
+
+    // permission parsed
+    bool permissionParsed = false;
+    if (segments[2].size() == 1) {
+        switch (segments[2][0]) {
+            case 'B':
+                mFeatureInfo.permission = SENSOR_PERMISSION_BODY_SENSORS;
+                permissionParsed = true;
+                break;
+            case '0':
+                mFeatureInfo.permission = "";
+                permissionParsed = true;
+                break;
+            default:
+                LOG_E << "Undefined permission designation " << segments[2] << LOG_ENDL;
+        }
+    }
+
+    // wake up
+    bool wakeUpParsed = false;
+    if (segments[3].size() == 1) {
+        switch (segments[3][0]) {
+            case 'W':
+                mFeatureInfo.isWakeUp = true;
+                wakeUpParsed = true;
+                break;
+            case 'N':
+                mFeatureInfo.isWakeUp = false;
+                wakeUpParsed = true;
+                break;
+            default:
+                LOG_E << "Undefined wake up designation " << segments[3] << LOG_ENDL;
+        }
+    }
+
+    int ret = typeParsed && reportingModeParsed && permissionParsed && wakeUpParsed;
+    if (!ret) {
+        LOG_D << "detectAndroidCustomSensor typeParsed: " << typeParsed
+              << " reportingModeParsed: "  << reportingModeParsed
+              << " permissionParsed: " << permissionParsed
+              << " wakeUpParsed: " << wakeUpParsed << LOG_ENDL;
+    }
+    return ret;
+}
+
+bool HidRawSensor::findSensorControlUsage(const std::vector<HidParser::ReportPacket> &packets) {
+    using namespace Hid::Sensor::PropertyUsage;
+    using namespace Hid::Sensor::RawMinMax;
+
+    //REPORTING_STATE
+    const HidParser::ReportItem *reportingState
+            = find(packets, REPORTING_STATE, HidParser::REPORT_TYPE_FEATURE);
+
+    if (reportingState == nullptr
+            || !reportingState->isByteAligned()
+            || reportingState->bitSize != 8
+            || reportingState->minRaw != REPORTING_STATE_MIN
+            || reportingState->maxRaw != REPORTING_STATE_MAX) {
+        LOG_W << "Cannot find valid reporting state feature" << LOG_ENDL;
+    } else {
+        mReportingStateId = reportingState->id;
+        mReportingStateOffset = reportingState->bitOffset / 8;
+    }
+
+    //POWER_STATE
+    const HidParser::ReportItem *powerState
+            = find(packets, POWER_STATE, HidParser::REPORT_TYPE_FEATURE);
+    if (powerState == nullptr
+            || !powerState->isByteAligned()
+            || powerState->bitSize != 8
+            || powerState->minRaw != POWER_STATE_MIN
+            || powerState->maxRaw != POWER_STATE_MAX) {
+        LOG_W << "Cannot find valid power state feature" << LOG_ENDL;
+    } else {
+        mPowerStateId = powerState->id;
+        mPowerStateOffset = powerState->bitOffset / 8;
+    }
+
+    //REPORT_INTERVAL
+    const HidParser::ReportItem *reportInterval
+            = find(packets, REPORT_INTERVAL, HidParser::REPORT_TYPE_FEATURE);
+    if (reportInterval == nullptr
+            || !reportInterval->isByteAligned()
+            || reportInterval->minRaw < 0
+            || (reportInterval->bitSize != 16 && reportInterval->bitSize != 32)) {
+        LOG_W << "Cannot find valid report interval feature" << LOG_ENDL;
+    } else {
+        mReportIntervalId = reportInterval->id;
+        mReportIntervalOffset = reportInterval->bitOffset / 8;
+        mReportIntervalSize = reportInterval->bitSize / 8;
+
+        mFeatureInfo.minDelay = std::max(static_cast<int64_t>(1), reportInterval->minRaw) * 1000;
+        mFeatureInfo.maxDelay = std::min(static_cast<int64_t>(1000000),
+                                    reportInterval->maxRaw) * 1000; // maximum 1000 second
+    }
+    return true;
+    return (mPowerStateId >= 0 || mReportingStateId >= 0) && mReportIntervalId >= 0;
+}
+
+const sensor_t* HidRawSensor::getSensor() const {
+    return &mSensor;
+}
+
+void HidRawSensor::getUuid(uint8_t* uuid) const {
+    memcpy(uuid, mFeatureInfo.uuid, sizeof(mFeatureInfo.uuid));
+}
+
+int HidRawSensor::enable(bool enable) {
+    using namespace Hid::Sensor::StateValue;
+    SP(HidDevice) device = PROMOTE(mDevice);
+
+    if (device == nullptr) {
+        return NO_INIT;
+    }
+
+    if (enable == mEnabled) {
+        return NO_ERROR;
+    }
+
+    std::vector<uint8_t> buffer;
+    bool setPowerOk = true;
+    if (mPowerStateId >= 0) {
+        setPowerOk = false;
+        uint8_t id = static_cast<uint8_t>(mPowerStateId);
+        if (device->getFeature(id, &buffer)
+                && buffer.size() > mPowerStateOffset) {
+            buffer[mPowerStateOffset] = enable ? POWER_STATE_FULL_POWER : POWER_STATE_POWER_OFF;
+            setPowerOk = device->setFeature(id, buffer);
+        } else {
+            LOG_E << "enable: changing POWER STATE failed" << LOG_ENDL;
+        }
+    }
+
+    bool setReportingOk = true;
+    if (mReportingStateId >= 0) {
+        setReportingOk = false;
+        uint8_t id = static_cast<uint8_t>(mReportingStateId);
+        if (device->getFeature(id, &buffer)
+                && buffer.size() > mReportingStateOffset) {
+            buffer[mReportingStateOffset]
+                    = enable ? REPORTING_STATE_ALL_EVENT : REPORTING_STATE_NO_EVENT;
+            setReportingOk = device->setFeature(id, buffer);
+        } else {
+            LOG_E << "enable: changing REPORTING STATE failed" << LOG_ENDL;
+        }
+    }
+
+    if (setPowerOk && setReportingOk) {
+        mEnabled = enable;
+        return NO_ERROR;
+    } else {
+        return INVALID_OPERATION;
+    }
+}
+
+int HidRawSensor::batch(int64_t samplingPeriod, int64_t batchingPeriod) {
+    SP(HidDevice) device = PROMOTE(mDevice);
+    if (device == nullptr) {
+        return NO_INIT;
+    }
+
+    if (samplingPeriod < 0 || batchingPeriod < 0) {
+        return BAD_VALUE;
+    }
+
+    bool needRefresh = mSamplingPeriod != samplingPeriod || mBatchingPeriod != batchingPeriod;
+    std::vector<uint8_t> buffer;
+
+    bool ok = true;
+    if (needRefresh && mReportIntervalId >= 0) {
+        ok = false;
+        uint8_t id = static_cast<uint8_t>(mReportIntervalId);
+        if (device->getFeature(id, &buffer)
+                && buffer.size() >= mReportIntervalOffset + mReportIntervalSize) {
+            int64_t periodMs = samplingPeriod / 1000000; //ns -> ms
+            switch (mReportIntervalSize) {
+                case sizeof(uint16_t):
+                    periodMs = std::min(periodMs, static_cast<int64_t>(UINT16_MAX));
+                    buffer[mReportIntervalOffset] = periodMs & 0xFF;
+                    buffer[mReportIntervalOffset + 1] = (periodMs >> 8) & 0xFF;
+                case sizeof(uint32_t):
+                    periodMs = std::min(periodMs, static_cast<int64_t>(UINT32_MAX));
+                    buffer[mReportIntervalOffset] = periodMs & 0xFF;
+                    buffer[mReportIntervalOffset + 1] = (periodMs >> 8) & 0xFF;
+                    buffer[mReportIntervalOffset + 2] = (periodMs >> 16) & 0xFF;
+                    buffer[mReportIntervalOffset + 3] = (periodMs >> 24) & 0xFF;
+            }
+            ok = device->setFeature(id, buffer);
+        }
+    }
+
+    if (ok) {
+        mSamplingPeriod = samplingPeriod;
+        mBatchingPeriod = batchingPeriod;
+        return NO_ERROR;
+    } else {
+        return INVALID_OPERATION;
+    }
+}
+
+void HidRawSensor::handleInput(uint8_t id, const std::vector<uint8_t> &message) {
+    if (id != mInputReportId || mEnabled == false) {
+        return;
+    }
+    sensors_event_t event = {
+        .version = sizeof(event),
+        .sensor = -1,
+        .type = mSensor.type
+    };
+    bool valid = true;
+    for (const auto &rec : mTranslateTable) {
+        int64_t v = (message[rec.byteOffset + rec.byteSize - 1] & 0x80) ? -1 : 0;
+        for (int i = static_cast<int>(rec.byteSize) - 1; i >= 0; --i) {
+            v = (v << 8) | message[rec.byteOffset + i]; // HID is little endian
+        }
+
+        switch (rec.type) {
+            case TYPE_FLOAT:
+                if (v > rec.maxValue || v < rec.minValue) {
+                    valid = false;
+                }
+                event.data[rec.index] = rec.a * (v + rec.b);
+                break;
+            case TYPE_INT64:
+                if (v > rec.maxValue || v < rec.minValue) {
+                    valid = false;
+                }
+                event.u64.data[rec.index] = v + rec.b;
+                break;
+            case TYPE_ACCURACY:
+                event.magnetic.status = (v & 0xFF) + rec.b;
+                break;
+        }
+    }
+    if (!valid) {
+        LOG_V << "Range error observed in decoding, discard" << LOG_ENDL;
+    }
+    event.timestamp = -1;
+    generateEvent(event);
+}
+
+std::string HidRawSensor::dump() const {
+    std::ostringstream ss;
+    ss << "Feature Values " << LOG_ENDL
+          << "  name: " << mFeatureInfo.name << LOG_ENDL
+          << "  vendor: " << mFeatureInfo.vendor << LOG_ENDL
+          << "  permission: " << mFeatureInfo.permission << LOG_ENDL
+          << "  typeString: " << mFeatureInfo.typeString << LOG_ENDL
+          << "  type: " << mFeatureInfo.type << LOG_ENDL
+          << "  maxRange: " << mFeatureInfo.maxRange << LOG_ENDL
+          << "  resolution: " << mFeatureInfo.resolution << LOG_ENDL
+          << "  power: " << mFeatureInfo.power << LOG_ENDL
+          << "  minDelay: " << mFeatureInfo.minDelay << LOG_ENDL
+          << "  maxDelay: " << mFeatureInfo.maxDelay << LOG_ENDL
+          << "  fifoSize: " << mFeatureInfo.fifoSize << LOG_ENDL
+          << "  fifoMaxSize: " << mFeatureInfo.fifoMaxSize << LOG_ENDL
+          << "  reportModeFlag: " << mFeatureInfo.reportModeFlag << LOG_ENDL
+          << "  isWakeUp: " << (mFeatureInfo.isWakeUp ? "true" : "false") << LOG_ENDL
+          << "  uniqueId: " << mFeatureInfo.uniqueId << LOG_ENDL
+          << "  uuid: ";
+
+    ss << std::hex << std::setfill('0');
+    for (auto d : mFeatureInfo.uuid) {
+          ss << std::setw(2) << static_cast<int>(d) << " ";
+    }
+    ss << std::dec << std::setfill(' ') << LOG_ENDL;
+
+    ss << "Input report id: " << mInputReportId << LOG_ENDL;
+    for (const auto &t : mTranslateTable) {
+        ss << "  type, index: " << t.type << ", " << t.index
+              << "; min,max: " << t.minValue << ", " << t.maxValue
+              << "; byte-offset,size: " << t.byteOffset << ", " << t.byteSize
+              << "; scaling,bias: " << t.a << ", " << t.b << LOG_ENDL;
+    }
+
+    ss << "Control features: " << LOG_ENDL;
+    ss << "  Power state ";
+    if (mPowerStateId >= 0) {
+        ss << "found, id: " << mPowerStateId
+              << " offset: " << mPowerStateOffset << LOG_ENDL;
+    } else {
+        ss << "not found" << LOG_ENDL;
+    }
+
+    ss << "  Reporting state ";
+    if (mReportingStateId >= 0) {
+        ss << "found, id: " << mReportingStateId
+              << " offset: " << mReportingStateOffset << LOG_ENDL;
+    } else {
+        ss << "not found" << LOG_ENDL;
+    }
+
+    ss << "  Report interval ";
+    if (mReportIntervalId >= 0) {
+        ss << "found, id: " << mReportIntervalId
+              << " offset: " << mReportIntervalOffset
+              << " size: " << mReportIntervalSize << LOG_ENDL;
+    } else {
+        ss << "not found" << LOG_ENDL;
+    }
+    return ss.str();
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h
new file mode 100644
index 0000000..2dd32b6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
+
+#include "BaseSensorObject.h"
+#include "HidDevice.h"
+#include "Utils.h"
+
+#include <HidParser.h>
+#include <hardware/sensors.h>
+
+namespace android {
+namespace SensorHalExt {
+
+using HidUtil::HidParser;
+using ReportPacket = HidParser::ReportPacket;
+using ReportItem = HidParser::ReportItem;
+
+class HidRawSensor : public BaseSensorObject {
+    friend class HidRawSensorTest;
+    friend class HidRawDeviceTest;
+public:
+    HidRawSensor(SP(HidDevice) device, uint32_t usage,
+                 const std::vector<HidParser::ReportPacket> &report);
+
+    // implements BaseSensorObject
+    virtual const sensor_t* getSensor() const;
+    virtual void getUuid(uint8_t* uuid) const;
+    virtual int enable(bool enable);
+    virtual int batch(int64_t samplePeriod, int64_t batchPeriod); // unit nano-seconds
+
+    // handle input report received
+    void handleInput(uint8_t id, const std::vector<uint8_t> &message);
+
+    // indicate if the HidRawSensor is a valid one
+    bool isValid() const { return mValid; };
+
+private:
+
+    // structure used for holding descriptor parse result for each report field
+    enum {
+        TYPE_FLOAT,
+        TYPE_INT64,
+        TYPE_ACCURACY
+    };
+    struct ReportTranslateRecord {
+        int type;
+        int index;
+        int64_t maxValue;
+        int64_t minValue;
+        size_t byteOffset;
+        size_t byteSize;
+        double a;
+        int64_t b;
+    };
+
+    // sensor related information parsed from HID descriptor
+    struct FeatureValue {
+        // information needed to furnish sensor_t structure (see hardware/sensors.h)
+        std::string name;
+        std::string vendor;
+        std::string permission;
+        std::string typeString;
+        int32_t type;
+        int version;
+        float maxRange;
+        float resolution;
+        float power;
+        int32_t minDelay;
+        int64_t maxDelay;
+        size_t fifoSize;
+        size_t fifoMaxSize;
+        uint32_t reportModeFlag;
+        bool isWakeUp;
+
+        // dynamic sensor specific
+        std::string uniqueId;
+        uint8_t uuid[16];
+
+        // if the device is custom sensor HID device that furnished android specific descriptors
+        bool isAndroidCustom;
+    };
+
+    // helper function to find the first report item with specified usage, type and id.
+    // if parameter id is omitted, this function looks for usage with all ids.
+    // return nullptr if nothing is found.
+    static const HidParser::ReportItem* find
+            (const std::vector<HidParser::ReportPacket> &packets,
+            unsigned int usage, int type, int id = -1);
+
+    // helper function to decode std::string from HID feature report buffer.
+    static bool decodeString(
+            const HidParser::ReportItem &report,
+            const std::vector<uint8_t> &buffer, std::string *d);
+
+    // initialize default feature values default based on hid device info
+    static void initFeatureValueFromHidDeviceInfo(
+            FeatureValue *featureValue, const HidDevice::HidDeviceInfo &info);
+
+    // populates feature values from descripitors and hid feature reports
+    bool populateFeatureValueFromFeatureReport(
+            FeatureValue *featureValue, const std::vector<HidParser::ReportPacket> &packets);
+
+    // validate feature values and construct sensor_t structure if values are ok.
+    bool validateFeatureValueAndBuildSensor();
+
+    // helper function to find sensor control feature usage from packets
+    bool findSensorControlUsage(const std::vector<HidParser::ReportPacket> &packets);
+
+    // try to parse sensor description feature value to see if it matches
+    // android specified custom sensor definition.
+    bool detectAndroidCustomSensor(const std::string &description);
+
+    // process HID sensor spec defined three axis sensors usages: accel, gyro, mag.
+    bool processTriAxisUsage(const std::vector<HidParser::ReportPacket> &packets,
+            uint32_t usageX, uint32_t usageY, uint32_t usageZ, double defaultScaling = 1);
+
+    // process HID snesor spec defined orientation(quaternion) sensor usages.
+    bool processQuaternionUsage(const std::vector<HidParser::ReportPacket> &packets);
+
+    // dump data for test/debug purpose
+    std::string dump() const;
+
+    // Features for control sensor
+    int mReportingStateId;
+    unsigned int mReportingStateOffset;
+
+    int mPowerStateId;
+    unsigned int mPowerStateOffset;
+
+    int mReportIntervalId;
+    unsigned int mReportIntervalOffset;
+    unsigned int mReportIntervalSize;
+
+    // Input report translate table
+    std::vector<ReportTranslateRecord> mTranslateTable;
+    unsigned mInputReportId;
+
+    FeatureValue mFeatureInfo;
+    sensor_t mSensor;
+
+    // runtime states variable
+    bool mEnabled;
+    int64_t mSamplingPeriod;    // ns
+    int64_t mBatchingPeriod;    // ns
+
+    WP(HidDevice) mDevice;
+    bool mValid;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp
new file mode 100644
index 0000000..6bf34bc
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidRawSensorDaemon.h"
+#include "ConnectionDetector.h"
+#include "DynamicSensorManager.h"
+#include "HidRawSensorDevice.h"
+
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <iomanip>
+#include <sstream>
+
+#define DEV_PATH                "/dev/"
+#define DEV_NAME_REGEX          "^hidraw[0-9]+$"
+
+namespace android {
+namespace SensorHalExt {
+
+HidRawSensorDaemon::HidRawSensorDaemon(DynamicSensorManager& manager)
+        : BaseDynamicSensorDaemon(manager) {
+    mDetector = new FileConnectionDetector(
+            this, std::string(DEV_PATH), std::string(DEV_NAME_REGEX));
+}
+
+BaseSensorVector HidRawSensorDaemon::createSensor(const std::string &deviceKey) {
+    BaseSensorVector ret;
+    sp<HidRawSensorDevice> device(HidRawSensorDevice::create(deviceKey));
+
+    if (device != nullptr) {
+        ALOGV("created HidRawSensorDevice(%p) successfully on device %s contains %zu sensors",
+              device.get(), deviceKey.c_str(), device->getSensors().size());
+
+        // convert type
+        for (auto &i : device->getSensors()) {
+            ret.push_back(i);
+        }
+        mHidRawSensorDevices.emplace(deviceKey, device);
+    } else {
+        ALOGE("failed to create HidRawSensorDevice object");
+    }
+
+    ALOGE("return %zu sensors", ret.size());
+    return ret;
+}
+
+void HidRawSensorDaemon::removeSensor(const std::string &deviceKey) {
+    mHidRawSensorDevices.erase(deviceKey);
+}
+
+} // namespace SensorHalExt
+} // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.h b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.h
new file mode 100644
index 0000000..fc4b2a2
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DAEMON_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DAEMON_H
+
+#include "BaseDynamicSensorDaemon.h"
+
+#include <HidParser.h>
+#include <hardware/sensors.h>
+#include <utils/Thread.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+
+using HidUtil::HidParser;
+using HidUtil::HidReport;
+using HidUtil::HidItem;
+
+namespace android {
+namespace SensorHalExt {
+
+class HidRawSensorDevice;
+class ConnectionDetector;
+
+class HidRawSensorDaemon : public BaseDynamicSensorDaemon {
+    friend class HidRawSensorDaemonTest;
+public:
+    HidRawSensorDaemon(DynamicSensorManager& manager);
+    virtual ~HidRawSensorDaemon() = default;
+private:
+    virtual BaseSensorVector createSensor(const std::string &deviceKey);
+    virtual void removeSensor(const std::string &deviceKey);
+
+    class HidRawSensor;
+    void registerExisting();
+
+    sp<ConnectionDetector> mDetector;
+    std::unordered_map<std::string, sp<HidRawSensorDevice>> mHidRawSensorDevices;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DAEMON_H
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
new file mode 100644
index 0000000..16e9060
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "HidRawSensorDevice.h"
+#include "HidRawSensor.h"
+#include "HidSensorDef.h"
+
+#include <utils/Log.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+#include <sys/ioctl.h>
+
+#include <set>
+
+namespace android {
+namespace SensorHalExt {
+
+using namespace Hid::Sensor::SensorTypeUsage;
+using namespace Hid::Sensor::PropertyUsage;
+
+const std::unordered_set<unsigned int> HidRawSensorDevice::sInterested{
+        ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM};
+
+sp<HidRawSensorDevice> HidRawSensorDevice::create(const std::string &devName) {
+    sp<HidRawSensorDevice> device(new HidRawSensorDevice(devName));
+    // remove +1 strong count added by constructor
+    device->decStrong(device.get());
+
+    if (device->mValid) {
+        return device;
+    } else {
+        return nullptr;
+    }
+}
+
+HidRawSensorDevice::HidRawSensorDevice(const std::string &devName)
+        : RefBase(), HidRawDevice(devName, sInterested),
+          Thread(false /*canCallJava*/), mValid(false) {
+    if (!HidRawDevice::isValid()) {
+        return;
+    }
+    // create HidRawSensor objects from digest
+    // HidRawSensor object will take sp<HidRawSensorDevice> as parameter, so increment strong count
+    // to prevent "this" being destructed.
+    this->incStrong(this);
+    for (const auto &digest : mDigestVector) { // for each usage - vec<ReportPacket> pair
+        uint32_t usage = static_cast<uint32_t>(digest.fullUsage);
+        sp<HidRawSensor> s(new HidRawSensor(this, usage, digest.packets));
+        if (s->isValid()) {
+            for (const auto &packet : digest.packets) {
+                if (packet.type == HidParser::REPORT_TYPE_INPUT) { // only used for input mapping
+                    mSensors.emplace(packet.id/* report id*/, s);
+                }
+            }
+        }
+    }
+    if (mSensors.size() == 0) {
+        return;
+    }
+
+    run("HidRawSensor");
+    mValid = true;
+}
+
+HidRawSensorDevice::~HidRawSensorDevice() {
+    ALOGV("~HidRawSensorDevice %p", this);
+    requestExitAndWait();
+    ALOGV("~HidRawSensorDevice %p, thread exited", this);
+}
+
+bool HidRawSensorDevice::threadLoop() {
+    ALOGV("Hid Raw Device thread started %p", this);
+    std::vector<uint8_t> buffer;
+    bool ret;
+    uint8_t usageId;
+
+    while(!Thread::exitPending()) {
+        ret = receiveReport(&usageId, &buffer);
+        if (!ret) {
+            break;
+        }
+
+        auto i = mSensors.find(usageId);
+        if (i == mSensors.end()) {
+            ALOGW("Input of unknow usage id %u received", usageId);
+            continue;
+        }
+
+        i->second->handleInput(usageId, buffer);
+    }
+
+    ALOGI("Hid Raw Device thread ended for %p", this);
+    return false;
+}
+
+BaseSensorVector HidRawSensorDevice::getSensors() const {
+    BaseSensorVector ret;
+    std::set<sp<BaseSensorObject>> set;
+    for (const auto &s : mSensors) {
+        if (set.find(s.second) == set.end()) {
+            ret.push_back(s.second);
+            set.insert(s.second);
+        }
+    }
+    return ret;
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDevice.h b/modules/sensors/dynamic_sensor/HidRawSensorDevice.h
new file mode 100644
index 0000000..06d435e
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDevice.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DEVICE_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DEVICE_H
+
+#include "BaseSensorObject.h"
+#include "BaseDynamicSensorDaemon.h" // BaseSensorVector
+#include "HidRawDevice.h"
+#include "HidRawSensor.h"
+
+#include <HidParser.h>
+#include <utils/Thread.h>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace SensorHalExt {
+
+class HidRawSensorDevice : public HidRawDevice, public Thread {
+public:
+    static sp<HidRawSensorDevice> create(const std::string &devName);
+    virtual ~HidRawSensorDevice();
+
+    // get a list of sensors associated with this device
+    BaseSensorVector getSensors() const;
+private:
+    static const std::unordered_set<unsigned int> sInterested;
+
+    // constructor will result in +1 strong count
+    explicit HidRawSensorDevice(const std::string &devName);
+    // implement function of Thread
+    virtual bool threadLoop() override;
+    std::unordered_map<unsigned int/*reportId*/, sp<HidRawSensor>> mSensors;
+    bool mValid;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+
diff --git a/modules/sensors/dynamic_sensor/HidSensorDef.h b/modules/sensors/dynamic_sensor/HidSensorDef.h
new file mode 100644
index 0000000..2728b28
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidSensorDef.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HID_SENSOR_DEF_H_
+#define HID_SENSOR_DEF_H_
+namespace Hid {
+namespace Sensor {
+namespace GeneralUsage {
+enum {
+    STATE = 0x200201,
+    EVENT = 0x200202,
+};
+
+} //namespace Usage
+namespace PropertyUsage {
+enum {
+    FRIENDLY_NAME = 0x200301,
+    MINIMUM_REPORT_INTERVAL = 0x200304,
+    PERSISTENT_UNIQUE_ID = 0x200302,
+    POWER_STATE = 0x200319,
+    RANGE_MAXIMUM = 0x200314,
+    RANGE_MINIMUM = 0x200315,
+    REPORTING_STATE = 0x200316,
+    REPORT_INTERVAL = 0x20030E,
+    RESOLUTION = 0x200313,
+    SAMPLING_RATE =0x200317,
+    SENSOR_CONNECTION_TYPE = 0x200309,
+    SENSOR_DESCRIPTION = 0x200308,
+    SENSOR_MANUFACTURER = 0x200305,
+    SENSOR_MODEL = 0x200306,
+    SENSOR_SERIAL_NUMBER = 0x200307,
+    SENSOR_STATUS = 0x200303,
+};
+} // nsmespace PropertyUsage
+
+namespace SensorTypeUsage {
+enum {
+    ACCELEROMETER_3D = 0x200073,
+    COMPASS_3D = 0x200083,
+    CUSTOM = 0x2000E1,
+    DEVICE_ORIENTATION = 0x20008A,
+    GYROMETER_3D = 0x200076,
+};
+} // namespace SensorTypeUsage
+
+namespace ReportUsage {
+enum {
+    ACCELERATION_X_AXIS = 0x200453,
+    ACCELERATION_Y_AXIS = 0x200454,
+    ACCELERATION_Z_AXIS = 0x200455,
+    ANGULAR_VELOCITY_X_AXIS = 0x200457,
+    ANGULAR_VELOCITY_Y_AXIS = 0x200458,
+    ANGULAR_VELOCITY_Z_AXIS = 0x200459,
+    CUSTOM_VALUE_1 = 0x200544,
+    CUSTOM_VALUE_2 = 0x200545,
+    CUSTOM_VALUE_3 = 0x200546,
+    CUSTOM_VALUE_4 = 0x200547,
+    CUSTOM_VALUE_5 = 0x200548,
+    CUSTOM_VALUE_6 = 0x200549,
+    MAGNETIC_FLUX_X_AXIS = 0x200485,
+    MAGNETIC_FLUX_Y_AXIS = 0x200486,
+    MAGNETIC_FLUX_Z_AXIS = 0x200487,
+    MAGNETOMETER_ACCURACY = 0x200488,
+    ORIENTATION_QUATERNION = 0x200483,
+};
+} // namespace ReportUsage
+
+namespace RawMinMax {
+enum {
+    REPORTING_STATE_MIN = 0,
+    REPORTING_STATE_MAX = 5,
+    POWER_STATE_MIN = 0,
+    POWER_STATE_MAX = 5,
+};
+} // namespace RawMinMax
+
+namespace StateValue {
+enum {
+    POWER_STATE_FULL_POWER = 1,
+    POWER_STATE_POWER_OFF = 5,
+
+    REPORTING_STATE_ALL_EVENT = 1,
+    REPORTING_STATE_NO_EVENT = 0,
+};
+} // StateValue
+} // namespace Sensor
+} // namespace Hid
+#endif // HID_SENSOR_DEF_H_
+
diff --git a/modules/sensors/dynamic_sensor/HidUtils/Android.mk b/modules/sensors/dynamic_sensor/HidUtils/Android.mk
new file mode 100644
index 0000000..5a1d890
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/Android.mk
@@ -0,0 +1,99 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+COMMON_CFLAGS := -Wall -Werror -Wextra
+
+hidparser_src := \
+    HidGlobal.cpp \
+    HidItem.cpp \
+    HidLocal.cpp \
+    HidParser.cpp \
+    HidReport.cpp \
+    HidTree.cpp
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhidparser
+LOCAL_MODULE_TAGS := optional
+# indended to be used by hal components, thus propietary
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"HidUtil\"
+LOCAL_SRC_FILES := $(hidparser_src)
+LOCAL_SHARED_LIBRARIES := libbase
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_SHARED_LIBRARY)
+
+#
+# host side shared library (for host test, example, etc)
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhidparser_host
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+
+LOCAL_SRC_FILES := $(hidparser_src)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+#
+# Example of HidParser
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidparser_example
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+LOCAL_SRC_FILES := \
+    $(hidparser_src) \
+    test/HidParserExample.cpp \
+    test/TestHidDescriptor.cpp
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
+include $(BUILD_HOST_EXECUTABLE)
+
+#
+# Another example of HidParser
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidparser_example2
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+LOCAL_SRC_FILES := \
+    $(hidparser_src) \
+    test/HidParserExample2.cpp \
+    test/TestHidDescriptor.cpp
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
+include $(BUILD_HOST_EXECUTABLE)
+
+#
+# Test for TriState template
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := tristate_test
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+LOCAL_SRC_FILES := test/TriStateTest.cpp
+
+LOCAL_STATIC_LIBRARIES := \
+     libgtest \
+     libgtest_main
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidDefs.h b/modules/sensors/dynamic_sensor/HidUtils/HidDefs.h
new file mode 100644
index 0000000..05445db
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidDefs.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDDEFS_H_
+#define HIDUTIL_HIDDEFS_H_
+
+namespace HidUtil {
+
+// HID specification constants definition
+//
+// Definitions are from HID specification v1.11, which can be obtained from http://www.usb.org
+//
+// Preferred namespace for namespace restriction than enum class as enum class has strong type
+// which is inconvenient in a parser, in which input binary values has to be compared with these
+// definitions frequnetly.
+namespace HidDef {
+// Hid spec 6.2.2.3
+namespace TagType {
+enum {
+    MAIN,
+    GLOBAL,
+    LOCAL,
+    RESERVED
+};
+} // namespace TagType
+
+// HID spec 6.2.2.4
+namespace ReportFlag {
+enum {
+    DATA_CONST = 1,
+    ARRAY_VARIABLE = 2,
+    WRAP = 4,
+    NONLINEAR = 8,
+    NO_PREFERRED = 0x10,
+    NULL_STATE = 0x20,
+    VOLATILE = 0x40,
+    // bit 7 reserved
+    BUFFERED_BYTES = 0x100
+};
+} // namespace ReportFlag
+
+// HID spec 6.2.2.5
+namespace MainTag {
+enum {
+    INPUT = 8,
+    OUTPUT = 9,
+    COLLECTION = 10,
+    FEATURE = 11,
+    END_COLLECTION = 12,
+    LONG_ITEM = 15,
+};
+} // namespace MainTag
+
+// HID spec 6.2.2.6
+namespace CollectionType {
+enum {
+    PHYSICAL = 0,
+    APPLICATION,
+    LOGICAL,
+    REPORT,
+    NAMED_ARRAY,
+    USAGE_SWITCH,
+    USAGE_MODIFIER
+};
+} // namespace CollectionType
+
+// HID spec 6.2.2.7
+namespace GlobalTag {
+enum {
+    USAGE_PAGE,
+    LOGICAL_MINIMUM,
+    LOGICAL_MAXIMUM,
+    PHYSICAL_MINIMUM,
+    PHYSICAL_MAXIMUM,
+    UNIT_EXPONENT,
+    UNIT,
+    REPORT_SIZE,
+    REPORT_ID,
+    REPORT_COUNT,
+    PUSH,
+    POP
+};
+} //namespace GlobalTag
+
+// HID spec 6.2.2.8
+namespace LocalTag {
+enum HidLocalTag {
+    USAGE,
+    USAGE_MINIMUM,
+    USAGE_MAXIMUM,
+    DESIGNATOR_INDEX,
+    DESIGNATOR_MINIMUM,
+    DESIGNATOR_MAXIMUM,
+    // there is a hole here in the spec
+    STRING_INDEX = 7,
+    STRING_MINIMUM,
+    STRING_MAXIMUM,
+    DELIMITOR
+};
+} // namespace LocalTag
+
+} //namespace HidDef
+} //namespace HidUtil
+
+#endif // HIDUTIL_HIDDEFS_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.cpp
new file mode 100644
index 0000000..8a4713b
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidGlobal.h"
+#include "HidLog.h"
+
+namespace HidUtil {
+using namespace HidDef::GlobalTag;
+
+bool HidGlobal::append(const HidItem &i) {
+    using namespace HidDef::TagType;
+    if (i.type != GLOBAL) {
+        LOG_E << "HidGlobal::append cannot process tag that is not global, " << i << LOG_ENDL;
+        return false;
+    }
+
+    if (i.tag == PUSH || i.tag == POP) {
+        LOG_E << "PUSH and POP should be handled in HidGlobalStack, " << i << LOG_ENDL;
+        return false;
+    }
+
+    int signedInteger;
+    unsigned unsignedInteger;
+    bool signedError = !i.dataAsSigned(&signedInteger);
+    bool unsignedError = !i.dataAsUnsigned(&unsignedInteger);
+
+    bool valueError = false;
+    bool ret = true;
+    switch (i.tag) {
+        case USAGE_PAGE:
+            usagePage = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case LOGICAL_MINIMUM:
+            logicalMin = signedInteger;
+            valueError = signedError;
+            break;
+        case LOGICAL_MAXIMUM:
+            logicalMax = signedInteger;
+            valueError = signedError;
+            break;
+        case PHYSICAL_MINIMUM:
+            physicalMin = signedInteger;
+            valueError = signedError;
+            break;
+        case PHYSICAL_MAXIMUM:
+            physicalMax = signedInteger;
+            valueError = signedError;
+            break;
+        case UNIT_EXPONENT:
+            exponent = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case UNIT:
+            unit = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case REPORT_SIZE:
+            reportSize = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case REPORT_ID:
+            reportId = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case REPORT_COUNT:
+            reportCount = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        default:
+            LOG_E << "unknown global tag, " << i << LOG_ENDL;
+            ret = false;
+    }
+
+    if (valueError) {
+        LOG_E << "Cannot get signed / unsigned data at " << i << LOG_ENDL;
+        ret = false;
+    }
+    return ret;
+}
+
+bool HidGlobalStack::append(const HidItem &i) {
+    using namespace HidDef::TagType;
+    if (i.type != GLOBAL) {
+        return false;
+    }
+
+    bool ret = true;
+    if (i.tag == PUSH) {
+        mStack.push_back(top());
+    } else if (i.tag == POP) {
+        mStack.pop_back();
+        if (mStack.size() == 0) {
+            mStack.push_back(HidGlobal()); // fail-safe
+            ret = false;
+        }
+    } else {
+        ret = mStack.back().append(i);
+    }
+    return ret;
+}
+
+HidGlobalStack::HidGlobalStack() {
+    // default element
+    mStack.push_back(HidGlobal());
+}
+
+const HidGlobal& HidGlobalStack::top() const {
+    return mStack.back();
+}
+
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.h b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.h
new file mode 100644
index 0000000..b9139d0
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDGLOBAL_H_
+#define HIDUTIL_HIDGLOBAL_H_
+
+#include "HidItem.h"
+#include "TriState.h"
+
+namespace HidUtil {
+// A set of global states that parser has to keep track during parsing.
+// They are all specified in HID spec v1.11 section 6.2.2.7
+struct HidGlobal {
+    // add a token and change global states, returns value indicates if operation is successful
+    bool append(const HidItem &i);
+
+    tri_uint usagePage;
+    tri_int  logicalMin;
+    tri_int  logicalMax;
+    tri_int  physicalMin;
+    tri_int  physicalMax;
+    tri_uint exponent;
+    tri_uint unit;
+    tri_uint reportSize;
+    tri_uint reportId;
+    tri_uint reportCount;
+};
+
+// HID specs allows PUSH and POP to save a snapshot of current global states and come back to the
+// saved sates later. HidStack manages this logic. Note that PUSH and POP are also HidItems, so
+// there is no explicit push and pop function in this stack implementation.
+class HidGlobalStack {
+public:
+    HidGlobalStack();
+
+    // add a token and change global states, returns value indicates if operation is successful
+    // it the token is push/pop, the stack push/pop accordingly.
+    bool append(const HidItem &i);
+
+    // get reference to top element on the stack
+    const HidGlobal& top() const;
+private:
+    std::vector<HidGlobal> mStack;
+};
+
+} //namespace HidUtil
+
+#endif // HIDUTIL_HIDGLOABL_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidItem.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidItem.cpp
new file mode 100644
index 0000000..e704db7
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidItem.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidItem.h"
+#include "HidDefs.h"
+#include "StreamIoUtil.h"
+#include <iostream>
+
+namespace HidUtil {
+
+bool HidItem::dataAsUnsigned(unsigned int *out) const  {
+    if (data.size() > 4 || data.size() == 0) {
+        return false;
+    }
+
+    *out = 0;
+    int shift = 0;
+
+    for (auto i : data) {
+        *out |= (i << shift);
+        shift += 8;
+    }
+    return true;
+}
+
+bool HidItem::dataAsSigned(int *out) const {
+    unsigned int u;
+    if (!dataAsUnsigned(&u)) {
+        return false;
+    }
+    size_t bitSize_1 = data.size() * 8 - 1;
+    unsigned int sign = u & (1 << bitSize_1);
+    *out = u | ((sign == 0) ? 0 : ( ~0 << bitSize_1));
+    return true;
+}
+
+std::vector<HidItem> HidItem::tokenize(const uint8_t *begin, size_t size) {
+    // construct a stream
+    charvectorbuf<unsigned char> buf(begin, size);
+    std::istream is(&buf);
+    return tokenize(is);
+}
+
+std::vector<HidItem> HidItem::tokenize(const std::vector<uint8_t> &descriptor) {
+    // construct a stream
+    charvectorbuf<unsigned char> buf(descriptor);
+    std::istream is(&buf);
+    return tokenize(is);
+}
+
+std::vector<HidItem> HidItem::tokenize(std::istream &is) {
+    std::vector<HidItem> hidToken;
+
+    // this is important to avoid skipping characters
+    is.unsetf(std::ios_base::skipws);
+    while (!is.eof()) {
+        HidItem i;
+        is >> i;
+        if (i.valid) {
+            hidToken.push_back(i);
+        } else {
+            break;
+        }
+    }
+    return hidToken;
+}
+
+std::istream& operator>>(std::istream &is, HidUtil::HidItem &h) {
+    using namespace HidUtil::HidDef::MainTag;
+    using namespace HidUtil::HidDef::TagType;
+
+    h.valid = false;
+    h.offset = is.tellg();
+    h.byteSize = 0;
+    unsigned char first;
+    is >> first;
+    if (!is.eof()) {
+        static const size_t lenTable[] = { 0, 1, 2, 4 };
+        size_t len = lenTable[first & 0x3]; // low 2 bits are length descriptor
+        h.tag = (first >> 4);
+        h.type = (first & 0xC) >> 2;
+
+        if (h.tag == LONG_ITEM && h.type == RESERVED) { // long item
+            //long item
+            unsigned char b = 0;
+            is >> b;
+            len = b;
+            is >> b;
+            h.tag = b;
+        }
+
+        h.data.resize(len);
+        for (auto &i : h.data) {
+            if (is.eof()) {
+                break;
+            }
+            is >> i;
+        }
+        h.byteSize = (ssize_t) is.tellg() - h.offset;
+        h.valid = !is.eof();
+    }
+
+    return is;
+}
+
+std::ostream& operator<<(std::ostream &os, const HidUtil::HidItem &h) {
+    os << "offset: " << h.offset << ", size: " << h.byteSize
+       << ", tag: " << h.tag << ", type: " << h.type << ", data: ";
+    if (h.data.empty()) {
+        os << "[empty]";
+    } else {
+        os << h.data.size() << " byte(s) {";
+        for (auto i : h.data) {
+            os << (int) i << ", ";
+        }
+        os << "}";
+    }
+    return os;
+}
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidItem.h b/modules/sensors/dynamic_sensor/HidUtils/HidItem.h
new file mode 100644
index 0000000..cec79e9
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidItem.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDITEM_H_
+#define HIDUTIL_HIDITEM_H_
+
+#include <cstdlib>
+#include <vector>
+#include <istream>
+#include <ostream>
+
+namespace HidUtil {
+
+struct HidItem {
+    bool valid;
+    unsigned int type;
+    unsigned int tag;
+    ssize_t offset;
+    ssize_t byteSize;
+    std::vector<uint8_t> data;
+
+    bool dataAsUnsigned(unsigned int *out) const;
+    bool dataAsSigned(int *out) const;
+
+    // friend stream functions
+    friend std::istream& operator>>(std::istream &is, HidItem &h);
+    friend std::ostream& operator<<(std::ostream &os, const HidItem &h);
+
+    // tokenize from a unsigned char vector
+    static std::vector<HidItem> tokenize(const std::vector<uint8_t> &descriptor);
+    static std::vector<HidItem> tokenize(const uint8_t *begin, size_t size);
+    static std::vector<HidItem> tokenize(std::istream &is);
+};
+
+// parsing in from binary stream
+std::istream& operator>>(std::istream &is, HidUtil::HidItem &h);
+
+// output as human readable string to stream
+std::ostream& operator<<(std::ostream &os, const HidUtil::HidItem &h);
+} //namespace HidUtil
+
+#endif // HIDUTIL_HIDITEM_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidLocal.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.cpp
new file mode 100644
index 0000000..8f17abe
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidLocal.h"
+#include "HidLog.h"
+#include <cstddef>
+
+namespace HidUtil {
+
+constexpr uint32_t INVALID_USAGE = 0xFFFF;
+constexpr uint32_t INVALID_DESIGNATOR = 0xFFFF;
+constexpr uint32_t INVALID_STRING = 0xFFFF;
+
+uint32_t HidLocal::getUsage(size_t index) const {
+    if (usage.empty()) {
+        return INVALID_USAGE;
+    }
+    return (index >= usage.size()) ? usage.back() : usage[index];
+}
+
+uint32_t HidLocal::getDesignator(size_t index) const {
+    if (designator.empty()) {
+        return INVALID_DESIGNATOR;
+    }
+    return (index >= designator.size()) ? designator.back() : designator[index];
+}
+
+uint32_t HidLocal::getString(size_t index) const {
+    if (string.empty()) {
+        return INVALID_STRING;
+    }
+    return (index >= string.size()) ? string.back() : string[index];
+}
+
+void HidLocal::clear() {
+    *this = HidLocal();
+}
+
+bool HidLocal::append(const HidItem &i) {
+    using namespace HidDef::LocalTag;
+
+    bool ret = true;
+    unsigned unsignedInteger;
+    bool unsignedError = !i.dataAsUnsigned(&unsignedInteger);
+    bool valueError = false;
+
+    switch (i.tag) {
+        case USAGE:
+            usage.push_back(unsignedInteger);
+            valueError = unsignedError;
+            break;
+        case USAGE_MINIMUM:
+            usageMin = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case USAGE_MAXIMUM:
+            if (!usageMin.isSet()) {
+                LOG_E << "usage min not set when saw usage max " << i << LOG_ENDL;
+                ret = false;
+            } else {
+                uint32_t usagemax = unsignedInteger;
+                valueError = unsignedError;
+                for (size_t j = usageMin.get(0); j <= usagemax; ++j) {
+                    usage.push_back(j);
+                }
+                usageMin.clear();
+            }
+            break;
+        case STRING_INDEX:
+            string.push_back(unsignedInteger);
+            valueError = unsignedError;
+            break;
+        case STRING_MINIMUM:
+            stringMin = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case STRING_MAXIMUM: {
+            if (!usageMin.isSet()) {
+                LOG_E << "string min not set when saw string max " << i << LOG_ENDL;
+                ret = false;
+            } else {
+                uint32_t stringMax = unsignedInteger;
+                valueError = unsignedError;
+                for (size_t j = stringMin.get(0); j <= stringMax; ++j) {
+                    string.push_back(j);
+                }
+                stringMin.clear();
+            }
+            break;
+        }
+        case DELIMITOR:
+            delimeter = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        default:
+            LOG_E << "unknown local tag, " << i << LOG_ENDL;
+            ret = false;
+    }
+    if (valueError) {
+        LOG_E << "Cannot get unsigned data at " << i << LOG_ENDL;
+        ret = false;
+    }
+    return ret;
+}
+} //namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidLocal.h b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.h
new file mode 100644
index 0000000..1c30b30
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDLOCAL_H_
+#define HIDUTIL_HIDLOCAL_H_
+
+#include "HidItem.h"
+#include "TriState.h"
+#include <cstddef>
+#include <vector>
+
+namespace HidUtil {
+
+// A set of local states that parser has to keep track during parsing.
+// They are all specified in HID spec v1.11 section 6.2.2.8
+struct HidLocal {
+    // add a token to change local states, return value indicates if operation is successful
+    bool append(const HidItem &i);
+    // clear all local states. This need to be done after each main tag
+    void clear();
+
+    // multiple usage, designator or strings may exist for single input/output/feature report
+    uint32_t getUsage(size_t index) const;
+    uint32_t getDesignator(size_t index) const;
+    uint32_t getString(size_t index) const;
+
+    std::vector<uint32_t> usage;
+    // keep track of usage min when expecting a usage max
+    tri_uint usageMin;
+
+    std::vector<uint32_t> designator;
+    // keep track of designator min when expecting designator max
+    tri_uint designatorMin;
+
+    std::vector<uint32_t> string;
+    // keep track of string min when expecting string max
+    tri_uint stringMin;
+
+    tri_uint delimeter;
+};
+} // namespace HidUtil
+
+#endif // HIDUTIL_HIDLOCAL_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidLog.h b/modules/sensors/dynamic_sensor/HidUtils/HidLog.h
new file mode 100644
index 0000000..677de57
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidLog.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDLOG_H_
+#define HIDUTIL_HIDLOG_H_
+
+#if defined(__ANDROID__) && !defined(LOG_TO_CONSOLE)
+#include <android-base/logging.h>
+#define LOG_ENDL ""
+#define LOG_E LOG(ERROR)
+#define LOG_W LOG(WARNING)
+#define LOG_I LOG(INFO)
+#define LOG_D LOG(DEBUG)
+#define LOG_V LOG(VERBOSE)
+#else
+#include <iostream>
+#define LOG_ENDL std::endl
+#define LOG_E (std::cerr << "E: ")
+#define LOG_W (std::cerr << "W: ")
+#define LOG_I (std::cerr << "I: ")
+#define LOG_D (std::cerr << "D: ")
+#define LOG_V (std::cerr << "V: ")
+#endif
+
+#endif // HIDUTIL_HIDLOG_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
new file mode 100644
index 0000000..5efaf65
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidParser.h"
+#include "HidLog.h"
+#include <iostream>
+#include <iomanip>
+
+namespace HidUtil {
+
+void HidParser::reset() {
+    mGlobalStack = HidGlobalStack();
+    mLocal = HidLocal();
+    mTree = std::make_shared<HidTreeNode>();
+    mCurrent = mTree;
+}
+
+bool HidParser::parse(const std::vector<HidItem> &token) {
+    // Clean up internal states of the parser for a new stream of descriptor token
+    reset();
+
+    bool ret = true;
+    using namespace HidDef::TagType;
+
+    for (auto &i : token) {
+        switch (i.type) {
+            case MAIN:
+                ret = processMainTag(i);
+                break;
+            case GLOBAL:
+                ret = mGlobalStack.append(i);
+                break;
+            case LOCAL:
+                ret = mLocal.append(i);
+                break;
+            default:
+                LOG_E << "HidParser found illegal HidItem: " << i << LOG_ENDL;
+                ret = false;
+        }
+
+        // in case a parse failure, quit prematurely
+        if (!ret) {
+            break;
+        }
+    }
+    return ret;
+}
+
+bool HidParser::processMainTag(const HidItem &i) {
+    using namespace HidDef::MainTag;
+    using namespace HidDef::ReportFlag;
+
+    bool ret = true;
+    switch (i.tag) {
+        case COLLECTION: {
+            unsigned int collectionType;
+            if (!i.dataAsUnsigned(&collectionType)) {
+                LOG_E << "Cannot get collection type at offset " << i.offset << LOG_ENDL;
+                ret = false;
+                break;
+            }
+            unsigned int fullUsage =
+                    mGlobalStack.top().usagePage.get(0) << 16 | mLocal.getUsage(0);
+            mCurrent = mCurrent->addChild(
+                    std::make_shared<HidTreeNode>(mCurrent, collectionType, fullUsage));
+            break;
+        }
+        case END_COLLECTION:
+            mCurrent = mCurrent->getParent();
+            if (!mCurrent) {
+                // trigger parse failure so that mCurrent will not be accessed
+                LOG_E << "unmatched END_COLLECTION at " << i.offset << LOG_ENDL;
+                ret = false;
+            }
+            break;
+        case INPUT:
+        case OUTPUT:
+        case FEATURE: {
+            unsigned int reportType = i.tag;
+            unsigned int flag;
+            if (!i.dataAsUnsigned(&flag)) {
+                LOG_E << "Cannot get report flag at offset " << i.offset << LOG_ENDL;
+                ret = false;
+                break;
+            }
+            const HidGlobal &top = mGlobalStack.top();
+
+            // usage page, local min/max, report size and count have to be defined at report
+            // definition.
+            if (!(top.usagePage.isSet() && top.logicalMin.isSet() && top.logicalMax.isSet()
+                  && top.reportSize.isSet() && top.reportCount.isSet())) {
+                LOG_E << "Report defined at " << i.offset
+                      << " does not have all mandatory fields set" << LOG_ENDL;
+                ret = false;
+                break;
+            }
+            if (top.reportSize.get(0) > 32) {
+                LOG_E << "Report defined at " << i.offset
+                      << " has unsupported report size(> 32 bit)" << LOG_ENDL;
+                ret = false;
+                break;
+            }
+
+            HidReport report(reportType, flag, top, mLocal);
+            mReport.push_back(report);
+            std::shared_ptr<HidTreeNode> node(new HidReportNode(mCurrent, report));
+            mCurrent->addChild(node);
+            break;
+        }
+        default:
+            LOG_E << "unknown main tag, " << i << LOG_ENDL;
+            ret = false;
+    }
+    // locals is cleared after any main tag according to HID spec
+    mLocal.clear();
+    return ret;
+}
+
+bool HidParser::parse(const unsigned char *begin, size_t size) {
+    std::vector<HidItem> hidItemVector = HidItem::tokenize(begin, size);
+    return parse(hidItemVector);
+}
+
+void HidParser::filterTree() {
+    if (mTree != nullptr) {
+        filterTree(mTree);
+    }
+}
+
+void HidParser::filterTree(std::shared_ptr<HidTreeNode> &node) {
+    if (node->isReportCollection()) {
+        std::shared_ptr<HidReportNode> reportNode =
+                std::static_pointer_cast<HidReportNode>(node->getChildren().front());
+        if (reportNode != nullptr) {
+            reportNode->collapse(node->getFullUsage());
+            node = reportNode;
+        }
+    } else {
+        for (auto &i : node->getChildren()) {
+            filterTree(i);
+        }
+    }
+}
+
+HidParser::DigestVector HidParser::generateDigest(
+        const std::unordered_set<unsigned int> &interestedUsage) {
+    DigestVector digestVector;
+    digest(&digestVector, mTree, interestedUsage);
+    return digestVector;
+}
+
+void HidParser::digest(HidParser::DigestVector *digestVector,
+                       const std::shared_ptr<HidTreeNode> &node,
+                       const std::unordered_set<unsigned int> &interestedUsage) {
+    if (digestVector == nullptr) {
+        return;
+    }
+
+    if (node->isUsageCollection()
+            && interestedUsage.find(node->getFullUsage()) != interestedUsage.end()) {
+        // this collection contains the usage interested
+        ReportSetGroup reportSetGroup;
+
+        // one layer deep search
+        for (auto &i : node->getChildren()) {
+            // skip all nodes that is not a report node
+            if (i->getNodeType() != HidTreeNode::TYPE_REPORT) {
+                continue;
+            }
+            const HidReport &report =
+                    std::static_pointer_cast<HidReportNode>(i)->getReport();
+
+            unsigned int id = report.getReportId();;
+            if (reportSetGroup.find(id) == reportSetGroup.end()) {
+                // create an id group if it is not created
+                reportSetGroup.emplace(id, ReportSet());
+            }
+
+            ReportSet &reportGroup = reportSetGroup[id];
+            switch(report.getType()) {
+                using namespace HidDef::MainTag;
+                case FEATURE:
+                    reportGroup[REPORT_TYPE_FEATURE].push_back(report);
+                    break;
+                case INPUT:
+                    reportGroup[REPORT_TYPE_INPUT].push_back(report);
+                    break;
+                case OUTPUT:
+                    reportGroup[REPORT_TYPE_OUTPUT].push_back(report);
+                    break;
+            }
+        }
+        ReportDigest digest = {
+            .fullUsage = node->getFullUsage(),
+            .packets = convertGroupToPacket(reportSetGroup)
+        };
+        digestVector->emplace_back(digest);
+    } else {
+        for (const auto &child : node->getChildren()) {
+            if (child->getNodeType() == HidTreeNode::TYPE_NORMAL) {
+                // only follow into collection nodes
+                digest(digestVector, child, interestedUsage);
+            }
+        }
+    }
+}
+
+std::vector<HidParser::ReportPacket> HidParser::convertGroupToPacket(
+        const HidParser::ReportSetGroup &group) {
+    std::vector<ReportPacket> packets;
+
+    const std::vector<int> types = {REPORT_TYPE_FEATURE, REPORT_TYPE_INPUT, REPORT_TYPE_OUTPUT};
+
+    for (const auto &setPair : group) {
+        unsigned int id = setPair.first;
+        for (auto type : types) {
+            const auto &reports = setPair.second[type]; // feature
+
+            // template
+            ReportPacket packet = {
+                .type = type,
+                .id = id,
+                .bitSize = 0
+            };
+
+            for (const auto &r : reports) {
+                auto logical = r.getLogicalRange();
+                auto physical = r.getPhysicalRange();
+
+                int64_t offset = physical.first - logical.first;
+                double scale = static_cast<double>((physical.second - physical.first))
+                        / (logical.second - logical.first);
+                scale *= r.getExponentValue();
+
+                ReportItem digest = {
+                    .usage = r.getFullUsage(),
+                    .id = id,
+                    .minRaw = logical.first,
+                    .maxRaw = logical.second,
+                    .a = scale,
+                    .b = offset,
+                    .bitOffset = packet.bitSize,
+                    .bitSize = r.getSize(),
+                    .count = r.getCount(),
+                    .unit = r.getUnit(),
+                };
+                packet.reports.push_back(digest);
+                packet.bitSize += digest.bitSize * digest.count;
+            }
+            if (!packet.reports.empty()) {
+                packets.push_back(std::move(packet));
+            }
+        }
+    }
+    return packets;
+}
+
+static std::string reportTypeToString(int reportType) {
+    switch (reportType) {
+        case HidParser::REPORT_TYPE_INPUT:
+            return "INPUT";
+        case HidParser::REPORT_TYPE_OUTPUT:
+            return "OUTPUT";
+        case HidParser::REPORT_TYPE_FEATURE:
+            return "FEATURE";
+        default:
+            return "INVALID REPORT";
+    }
+}
+
+std::ostream& operator<<(std::ostream &os, const HidParser::DigestVector &digests) {
+    for (const auto &i : digests) {
+        os << "Usage: 0x" << std::hex  << i.fullUsage << std::dec
+           << ", " << i.packets.size() << " report packet:" << LOG_ENDL;
+        for (const auto &packet : i.packets) {
+            os << reportTypeToString(packet.type) << " id: " << packet.id
+               << " size: " << packet.bitSize
+               << "b(" << packet.getByteSize() << "B), "
+               << packet.reports.size() << " entries" << LOG_ENDL;
+
+            for (const auto &report : packet.reports) {
+                double min, max;
+                report.decode(report.mask(report.minRaw), &min);
+                report.decode(report.mask(report.maxRaw), &max);
+
+                os << "  " << report.bitOffset << " size: " << report.bitSize
+                   << ", count: " << report.count
+                   << ", usage: " << std::hex << std::setfill('0') << std::setw(8)
+                   << report.usage << std::dec
+                   << ", min: " << report.minRaw << ", max: " << report.maxRaw
+                   << ", minDecoded: " << min
+                   << ", maxDecoded: " << max
+                   << ", a: " << report.a << ", b: " << report.b
+                   << std::hex
+                   << ", minRawHex: 0x" << report.mask(report.minRaw)
+                   << ", maxRawHex: 0x" << report.mask(report.maxRaw)
+                   << ", rawMasked: 0x" << report.rawMask()
+                   << std::dec << LOG_ENDL;
+            }
+        }
+        os << LOG_ENDL;
+    }
+    os << LOG_ENDL;
+    return os;
+}
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.h b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h
new file mode 100644
index 0000000..4ef5ec6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDPARSER_H_
+#define HIDUTIL_HIDPARSER_H_
+
+#include "HidItem.h"
+#include "HidTree.h"
+#include "HidGlobal.h"
+#include "HidLocal.h"
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <array>
+#include <ostream>
+
+namespace HidUtil {
+class HidParser {
+public:
+    enum {
+        REPORT_TYPE_FEATURE = 0,
+        REPORT_TYPE_INPUT = 1,
+        REPORT_TYPE_OUTPUT = 2
+    };
+
+    struct ReportItem;
+    struct ReportPacket;
+
+    // report (including input output and feature) grouped by full usage
+    struct ReportDigest {
+        unsigned int fullUsage;
+        std::vector<ReportPacket> packets;
+    };
+
+    typedef std::vector<ReportDigest> DigestVector;
+
+    // parse HID descriptor
+    bool parse(const std::vector<HidItem> &token);
+    bool parse(const unsigned char *begin, size_t size);
+
+    // filter the tree to eliminate single child report leaf node causes by usage array type
+    // reports
+    void filterTree();
+
+    // generate a list of report digest for all interested usage. It will automatically
+    // call filterTree().
+    DigestVector generateDigest(const std::unordered_set<unsigned int> &interestedUsage);
+
+    // get parsed tree (filtered or not filtered)
+    const std::shared_ptr<HidTreeNode> getTree() const { return mTree; }
+
+    // get all parsed report in a parsed form.
+    const std::vector<HidReport>& getReport() const { return mReport; }
+
+private:
+    typedef std::array<std::vector<HidReport>, 3> ReportSet;
+    typedef std::unordered_map<unsigned int /* reportId */, ReportSet> ReportSetGroup;
+
+    // helper subroutines
+    void reset();
+    bool processMainTag(const HidItem &i);
+    static void filterTree(std::shared_ptr<HidTreeNode> &node);
+    static void digest(
+            DigestVector *digestVector,
+            const std::shared_ptr<HidTreeNode> &node,
+            const std::unordered_set<unsigned int> &interestedUsage);
+    static std::vector<ReportPacket> convertGroupToPacket(const ReportSetGroup &group);
+
+    HidGlobalStack mGlobalStack;
+    HidLocal mLocal;
+    std::shared_ptr<HidTreeNode> mTree;
+    std::shared_ptr<HidTreeNode> mCurrent;
+    std::vector<HidReport> mReport;
+};
+
+struct HidParser::ReportItem {
+    unsigned int usage;
+    unsigned int id;
+    int type; // feature, input or output
+
+    int64_t minRaw;
+    int64_t maxRaw;
+
+    // conversion for float point values
+    // real value = (signExtendIfNeeded(raw) + b) * a
+    // raw value = mask(real/a - b);
+    //
+    // conversion for integer values
+    // real value = signExtendedIfNeeded(raw) + b;
+    // raw value = mask(real - b);
+    double a; // scaling
+    int64_t b; // offset
+    unsigned int unit;
+
+    size_t bitOffset;
+    size_t bitSize; // bit length per unit
+    size_t count;
+
+    // helper function
+    bool isSigned() const {
+        return minRaw < 0;
+    }
+
+    bool isByteAligned() const {
+        return (bitOffset & 7) == 0 && (bitSize & 7) == 0;
+    }
+
+    // convert raw values to unsigned format
+    uint32_t mask(int64_t input) const {
+        return static_cast<uint32_t>(input & rawMask());
+    }
+
+    bool decode(uint32_t input, double *output) const {
+        if (output == nullptr) {
+            return false;
+        }
+        int64_t s = signExtendIfNeeded(input);
+        if (s < minRaw || s > maxRaw) {
+            return false;
+        }
+        *output = (s + b) * a;
+        return true;
+    }
+
+    bool encode(double input, uint32_t *output) const {
+        if (output == nullptr) {
+            return false;
+        }
+        input = input / a - b;
+        if (input < minRaw || input > maxRaw) {
+            return false;
+        }
+        *output = static_cast<uint32_t>(static_cast<int64_t>(input) & rawMask());
+        return true;
+    }
+
+    int64_t rawMask() const {
+        constexpr int64_t one = 1;
+        return (one << bitSize) - 1;
+    }
+
+    int64_t signExtendIfNeeded(int64_t value) const {
+        return value | ((isSigned() && isNegative(value)) ? ~rawMask() : 0);
+    }
+
+    bool isNegative(int64_t value) const {
+        constexpr int64_t one = 1;
+        return ((one << (bitSize - 1)) & value) != 0;
+    }
+};
+
+// a collection of report item that forms a packet
+// this is the input output unit with HID hardware
+struct HidParser::ReportPacket {
+    std::vector<ReportItem> reports;
+    size_t bitSize;
+    int type; // REPORT_TYPE_FEATURE/INPUT/OUTPUT
+    unsigned int id;
+
+    size_t getByteSize() const { return (bitSize + 7) / 8; };
+};
+
+std::ostream& operator<<(std::ostream &os, const HidParser::DigestVector &digest2);
+} // namespace HidUtil
+
+#endif // HIDUTIL_HIDPARSER_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidReport.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidReport.cpp
new file mode 100644
index 0000000..9b2b78b
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidReport.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidReport.h"
+#include "HidDefs.h"
+#include <cmath>
+#include <sstream>
+#include <iomanip>
+
+namespace HidUtil {
+HidReport::HidReport(uint32_t type, uint32_t data,
+                     const HidGlobal &global, const HidLocal &local)
+        : mReportType(type),
+          mFlag(data),
+          mUsagePage(global.usagePage.get(0)),   // default value 0
+          mUsage(local.getUsage(0)),
+          mUsageVector(local.usage),
+          mLogicalMin(global.logicalMin.get(0)), // default value 0
+          mLogicalMax(global.logicalMax.get(0)),
+          mReportSize(global.reportSize),
+          mReportCount(global.reportCount),
+          mPhysicalMin(global.physicalMin),
+          mPhysicalMax(global.physicalMax),
+          mExponent(global.exponent),
+          mUnit(global.unit),
+          mReportId(global.reportId) { }
+
+std::string HidReport::getStringType() const {
+    return reportTypeToString(mReportType);
+}
+
+std::string HidReport::reportTypeToString(int type) {
+    using namespace HidDef::MainTag;
+    switch(type) {
+        case INPUT:
+            return "INPUT";
+        case OUTPUT:
+            return "OUTPUT";
+        case FEATURE:
+            return "FEATURE";
+        default:
+            return "<<UNKNOWN>>";
+    }
+}
+
+double HidReport::getExponentValue() const {
+    if (!mExponent.isSet()) {
+        return 1;
+    }
+    // default exponent is 0
+    int exponentInt = mExponent.get(0);
+    if (exponentInt > 15 || exponentInt < 0) {
+        return NAN;
+    }
+    return pow(10.0, static_cast<double>((exponentInt <= 7) ? exponentInt : exponentInt - 16));
+}
+
+std::string HidReport::getExponentString() const {
+    int exponentInt = mExponent.get(0);
+    if (exponentInt > 15 || exponentInt < 0) {
+        return "[error]";
+    }
+    return std::string("x10^")
+            + std::to_string((exponentInt <= 7) ? exponentInt : exponentInt - 16);
+}
+
+std::string HidReport::getUnitString() const {
+    if (!mUnit.isSet()) {
+        return "default";
+    }
+    return "[not implemented]";
+
+    std::ostringstream ret;
+    ret << std::hex << std::setfill('0') << std::setw(2) << mUnit.get(0);
+    return ret.str();
+}
+
+std::string HidReport::getFlagString() const {
+    using namespace HidDef::ReportFlag;
+    std::string ret;
+    ret += (mFlag & DATA_CONST) ? "Const " : "Data ";
+    ret += (mFlag & ARRAY_VARIABLE) ? "Variable " : "Array ";
+    ret += (mFlag & WRAP) ? "Wrap " : "";
+    ret += (mFlag & NONLINEAR) ? "Nonlinear " : "";
+    ret += (mFlag & NO_PREFERRED) ? "NoPreferred " : "";
+    ret += (mFlag & NULL_STATE) ? "NullState " : "";
+    ret += (mFlag & VOLATILE) ? "Volatile " : "";
+    ret += (mFlag & BUFFERED_BYTES) ? "BufferedBytes " : "";
+    return ret;
+}
+
+// isArray() will return true for reports that may contains multiple values, e.g. keyboard scan
+// code, which can have multiple value, each denoting a key pressed down at the same time. It will
+// return false if repor represent a vector or matrix.
+//
+// This slightly deviates from HID's definition, it is more convenient this way as matrix/vector
+// input is treated similarly as variables.
+bool HidReport::isArray() const {
+    using namespace HidDef::ReportFlag;
+    return (mFlag & ARRAY_VARIABLE) == 0 && mIsCollapsed;
+}
+
+bool HidReport::isVariable() const {
+    return !isArray();
+}
+
+bool HidReport::isData() const {
+    using namespace HidDef::ReportFlag;
+    return (mFlag & DATA_CONST) == 0;
+}
+
+std::ostream& operator<<(std::ostream& os, const HidReport& h) {
+    os << h.getStringType() << ", "
+       << "usage: " << std::hex << h.getFullUsage() << std::dec << ", ";
+
+    if (h.isData()) {
+        auto range = h.getLogicalRange();
+        os << "logMin: " << range.first << ", "
+           << "logMax: " << range.second << ", ";
+
+        if (range == h.getPhysicalRange()) {
+            os << "phy===log, ";
+        } else {
+            range = h.getPhysicalRange();
+            os << "phyMin: " << range.first << ", "
+               << "phyMax: " << range.second << ", ";
+        }
+
+        if (h.isArray()) {
+            os << "map: (" << std::hex;
+            for (auto i : h.getUsageVector()) {
+                os << i << ",";
+            }
+            os << "), " << std::dec;
+        }
+
+        os << "exponent: " << h.getExponentString() << ", "
+           << "unit: " << h.getUnitString() << ", ";
+    } else {
+        os << "constant: ";
+    }
+    os << "size: " << h.getSize() << "bit x " << h.getCount() << ", "
+       << "id: " << h.mReportId;
+
+    return os;
+}
+
+std::pair<int64_t, int64_t> HidReport::getLogicalRange() const {
+    int64_t a = mLogicalMin;
+    int64_t b = mLogicalMax;
+
+    if (a > b) {
+        // might be unsigned
+        a = a & ((static_cast<int64_t>(1) << getSize()) - 1);
+        b = b & ((static_cast<int64_t>(1) << getSize()) - 1);
+        if (a > b) {
+            // bad hid descriptor
+            return {0, 0};
+        }
+    }
+    return {a, b};
+}
+
+std::pair<int64_t, int64_t> HidReport::getPhysicalRange() const {
+    if (!(mPhysicalMin.isSet() && mPhysicalMax.isSet())) {
+        // physical range undefined, use logical range
+        return getLogicalRange();
+    }
+
+    int64_t a = mPhysicalMin.get(0);
+    int64_t b = mPhysicalMax.get(0);
+
+    if (a > b) {
+        a = a & ((static_cast<int64_t>(1) << getSize()) - 1);
+        b = b & ((static_cast<int64_t>(1) << getSize()) - 1);
+        if (a > b) {
+            return {0, 0};
+        }
+    }
+    return {a, b};
+}
+
+unsigned int HidReport::getFullUsage() const {
+    return mUsage | (mUsagePage << 16);
+}
+
+size_t HidReport::getSize() const {
+    return mReportSize;
+}
+
+size_t HidReport::getCount() const {
+    return mReportCount;
+}
+
+unsigned int HidReport::getUnit() const {
+    return mUnit.get(0); // default unit is 0 means default unit
+}
+
+unsigned HidReport::getReportId() const {
+    // if report id is not specified, it defaults to zero
+    return mReportId.get(0);
+}
+
+unsigned HidReport::getType() const {
+    return mReportType;
+}
+
+void HidReport::setCollapsed(uint32_t fullUsage) {
+    mUsage = fullUsage & 0xFFFF;
+    mUsagePage = fullUsage >> 16;
+    mIsCollapsed = true;
+}
+
+const std::vector<unsigned int>& HidReport::getUsageVector() const {
+    return mUsageVector;
+}
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidReport.h b/modules/sensors/dynamic_sensor/HidUtils/HidReport.h
new file mode 100644
index 0000000..9b01b68
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidReport.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDREPORT_H_
+#define HIDUTIL_HIDREPORT_H_
+
+#include "HidGlobal.h"
+#include "HidLocal.h"
+#include "TriState.h"
+#include <cstdint>
+#include <memory>
+#include <iostream>
+#include <utility>
+
+namespace HidUtil {
+
+class HidParser;
+class HidTreeNode;
+
+// HidReport represent an input, output or feature report
+class HidReport {
+    friend std::ostream& operator<<(std::ostream& os, const HidReport& h);
+public:
+    HidReport(uint32_t type_, uint32_t data, const HidGlobal &global, const HidLocal &local);
+
+    // This is called during parsing process when the parser regroups multi-valued report into one
+    void setCollapsed(uint32_t fullUsage);
+
+    // get report id
+    unsigned int getReportId() const;
+    // get type of report, return constant of HidDef::MainTag
+    unsigned int getType() const;
+    // Full sensor usage
+    unsigned int getFullUsage() const;
+
+    // binary properties
+    bool isArray() const;
+    bool isData() const;
+    bool isVariable() const;
+
+    // logical and physical value range
+    std::pair<int64_t, int64_t> getLogicalRange() const;
+    std::pair<int64_t, int64_t> getPhysicalRange() const;
+    double getExponentValue() const;
+
+    // return HID unit nibbles in an unsigned int
+    unsigned int getUnit() const;
+
+    // size in bits
+    size_t getSize() const;
+    // dimension (if it is vector/matrix) or number of concurrent input values
+    // it is also used to calculate memory foot print
+    size_t getCount() const;
+
+    // for output to stream
+    static std::string reportTypeToString(int type);
+    std::string getStringType() const;
+    std::string getExponentString() const;
+    std::string getUnitString() const;
+    std::string getFlagString() const;
+    const std::vector<unsigned int>& getUsageVector() const;
+private:
+    bool mIsCollapsed;
+
+    // mandatary fields
+    unsigned int mReportType;
+    unsigned int mFlag;
+    unsigned int mUsagePage;
+    unsigned int mUsage;
+    std::vector<unsigned int> mUsageVector;
+
+    int mLogicalMin;        // 32 bit is enough
+    int mLogicalMax;
+    unsigned int mReportSize;
+    unsigned int mReportCount;
+
+    // these below are optional
+    tri_int mPhysicalMin;
+    tri_int mPhysicalMax;
+
+    tri_uint mExponent;
+    tri_uint mUnit;
+    tri_uint mReportId;
+};
+
+std::ostream& operator<<(std::ostream& os, const HidReport& h);
+} // namespace HidUtil
+#endif // HIDUTIL_HIDREPORT_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidTree.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidTree.cpp
new file mode 100644
index 0000000..9204135
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidTree.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidLog.h"
+#include "HidTree.h"
+#include <memory>
+
+namespace HidUtil {
+
+// HidTreeNode
+HidTreeNode::HidTreeNode() : mNodeType(TYPE_UNINITIALIZED), mData(0), mFullUsage(0) {
+}
+
+HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
+                         uint32_t data, uint32_t fullUsage, int nodeType)
+        : mNodeType(nodeType), mData(data),
+        mFullUsage(fullUsage), mParent(parent) {
+}
+
+HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
+                         uint32_t data, uint32_t fullUsage)
+        : mNodeType(TYPE_NORMAL), mData(data),
+        mFullUsage(fullUsage), mParent(parent) {
+}
+
+void HidTreeNode::outputRecursive(std::ostream &os, int level) const {
+    insertIndentation(os, level);
+    os << "Node data: " << mData
+       << ", usage " << std::hex << mFullUsage << std::dec << LOG_ENDL;
+
+    for (auto &child : mChildren) {
+        child->outputRecursive(os, level + 1);
+    }
+}
+
+std::shared_ptr<HidTreeNode> HidTreeNode::deepCopy(
+        std::shared_ptr<HidTreeNode> parent) const {
+    std::shared_ptr<HidTreeNode> copy(new HidTreeNode(parent, mData, mFullUsage, mNodeType));
+    for (auto &i : mChildren) {
+        copy->mChildren.push_back(i->deepCopy(copy));
+    }
+    return copy;
+}
+
+void HidTreeNode::insertIndentation(std::ostream &os, int level) const {
+    constexpr char indentCharacter = '\t';
+    std::fill_n(std::ostreambuf_iterator<char>(os), level, indentCharacter);
+}
+
+std::shared_ptr<HidTreeNode> HidTreeNode::addChild(std::shared_ptr<HidTreeNode> child) {
+    mChildren.push_back(child);
+    return child;
+}
+
+std::shared_ptr<HidTreeNode> HidTreeNode::getParent() const {
+    return mParent.lock();
+}
+
+bool HidTreeNode::isReportCollection() const {
+    return mNodeType == TYPE_NORMAL && mChildren.size() == 1
+            && mChildren.front()->mNodeType == TYPE_REPORT;
+}
+
+unsigned int HidTreeNode::getFullUsage() const {
+    return mFullUsage;
+}
+
+std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() {
+    return mChildren;
+}
+
+const std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() const {
+    return mChildren;
+}
+
+bool HidTreeNode::isUsageCollection() const {
+    using namespace HidDef::CollectionType;
+    return mNodeType == TYPE_NORMAL && (mData == PHYSICAL || mData == APPLICATION);
+}
+
+int HidTreeNode::getNodeType() const {
+    return mNodeType;
+}
+
+std::ostream& operator<<(std::ostream& os, const HidTreeNode& n) {
+    n.outputRecursive(os, 0);
+    return os;
+}
+
+// HidReportNode
+HidReportNode::HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report)
+    : HidTreeNode(parent, 0 /*data*/, 0 /*fullUsage*/, TYPE_REPORT), mReport(report) {
+}
+
+void HidReportNode::outputRecursive(std::ostream &os, int level) const {
+    insertIndentation(os, level);
+    os << mReport << LOG_ENDL;
+}
+
+std::shared_ptr<HidTreeNode> HidReportNode::deepCopy(
+        std::shared_ptr<HidTreeNode> parent) const {
+    std::shared_ptr<HidTreeNode> copy(new HidReportNode(parent, mReport));
+    return copy;
+}
+
+const HidReport& HidReportNode::getReport() const {
+    return mReport;
+}
+
+void HidReportNode::collapse(unsigned int newUsage) {
+    mReport.setCollapsed(newUsage);
+}
+
+} //namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidTree.h b/modules/sensors/dynamic_sensor/HidUtils/HidTree.h
new file mode 100644
index 0000000..2752007
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidTree.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDTREE_H_
+#define HIDUTIL_HIDTREE_H_
+
+#include "HidReport.h"
+
+#include <cstddef>
+#include <vector>
+#include <iostream>
+
+namespace HidUtil {
+
+// HID report parser output tree node
+class HidTreeNode {
+    friend std::ostream& operator<<(std::ostream& os, const HidTreeNode& n);
+public:
+    enum {
+        TYPE_UNINITIALIZED = 0,
+        TYPE_NORMAL = 1,
+        TYPE_REPORT = 2     // can be cast to HidReportNode
+    };
+    HidTreeNode();
+    HidTreeNode(std::shared_ptr<HidTreeNode> parent, uint32_t data, uint32_t fullUsage);
+
+    virtual ~HidTreeNode() = default;
+
+    // make a deep copy of tree at and below this node and attach it to specified parent node
+    virtual std::shared_ptr<HidTreeNode> deepCopy(
+          std::shared_ptr<HidTreeNode> parent = nullptr) const;
+
+    // add child to this node
+    std::shared_ptr<HidTreeNode> addChild(std::shared_ptr<HidTreeNode> child);
+
+    // get all children of a node
+    std::vector<std::shared_ptr<HidTreeNode>>& getChildren();
+    const std::vector<std::shared_ptr<HidTreeNode>>& getChildren() const;
+
+    // get parent (nullptr if it is root node or if lock weak_ptr failed)
+    std::shared_ptr<HidTreeNode> getParent() const;
+
+    // access usage of this node
+    unsigned int getFullUsage() const;
+
+    bool isReportCollection() const;
+    bool isUsageCollection() const;
+    int getNodeType() const;
+protected:
+    // for derived class to define different nodeType
+    HidTreeNode(std::shared_ptr<HidTreeNode> parent,
+              uint32_t data, uint32_t fullUsage, int nodeType);
+
+    // helper for stream output
+    void insertIndentation(std::ostream &os, int level) const;
+private:
+    // helper for stream output
+    virtual void outputRecursive(std::ostream& os, int level) const;
+
+    int mNodeType;
+    uint32_t mData;
+    uint32_t mFullUsage;
+
+    std::vector<std::shared_ptr<HidTreeNode>> mChildren;
+    std::weak_ptr<HidTreeNode> mParent;
+};
+
+// Tree node that corresponds to an input, output or feature report
+class HidReportNode : public HidTreeNode {
+public:
+    HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report);
+
+    virtual std::shared_ptr<HidTreeNode> deepCopy(
+          std::shared_ptr<HidTreeNode> parent = nullptr) const override;
+
+    // obtain HidReport attached to this node
+    const HidReport& getReport() const;
+
+    // reset usage of node and set underlying report to collapsed
+    void collapse(unsigned int newUsage);
+private:
+    virtual void outputRecursive(std::ostream &os, int level) const override;
+
+    HidReport mReport;
+};
+
+std::ostream& operator<<(std::ostream& os, const HidTreeNode& n);
+
+} // namespace HidUtil
+
+#endif // HIDUTIL_HIDTREE_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/StreamIoUtil.h b/modules/sensors/dynamic_sensor/HidUtils/StreamIoUtil.h
new file mode 100644
index 0000000..45a94b6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/StreamIoUtil.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_STREAM_IO_UTIL_H_
+#define HIDUTIL_STREAM_IO_UTIL_H_
+
+#include "HidLog.h"
+#include <istream>
+#include <iomanip>
+#include <sstream>
+#include <vector>
+#include <cassert>
+
+namespace HidUtil {
+
+template<typename CharT>
+class charvectorbuf : public std::streambuf { // class name is consistent with std lib
+    static_assert(std::is_const<CharT>::value == false, "cannot use const type");
+public:
+    // r/w buffer constructors
+    charvectorbuf(std::vector<CharT> &vec) {
+        init(vec.data(), vec.size());
+    }
+
+    charvectorbuf(CharT *begin, CharT *end) {
+        assert(end >= begin);
+        init(begin, end - begin);
+    }
+
+    charvectorbuf(CharT *begin, size_t size) {
+        init(begin, size);
+    }
+
+    // r/o buffer constructor
+    charvectorbuf(const std::vector<CharT> &vec) {
+        init(vec.data(), vec.size());
+    }
+
+    charvectorbuf(const CharT *begin, const CharT *end) {
+        assert(end >= begin);
+        init(begin, end - begin);
+    }
+
+    charvectorbuf(const CharT *begin, size_t size) {
+        init(begin, size);
+    }
+ protected:
+    virtual std::streampos seekpos(
+            std::streampos sp, std::ios_base::openmode which =
+            std::ios_base::in | std::ios_base::out) override {
+        return seekoff(std::streamoff(sp), std::ios_base::beg, which);
+    }
+
+    // this is needed to use ftell() on stream
+    virtual std::streampos seekoff(
+            std::streamoff off, std::ios_base::seekdir way,
+            std::ios_base::openmode which =
+            std::ios_base::in | std::ios_base::out) override {
+
+        // pptr() == nullptr: read-only
+        assert(pptr() == nullptr || egptr() - eback() == epptr() - pbase());
+        bool in = which & std::ios_base::in;
+        bool out = which & std::ios_base::out;
+        pos_type end = egptr() - eback();
+
+        if (!in && !out) {
+            return pos_type(-1);
+        }
+
+        if (in && out && way == std::ios_base::cur) {
+            return pos_type(-1);
+        }
+
+        off_type noff;
+        switch (way) {
+            case std::ios_base::beg:
+                noff = 0;
+                break;
+            case std::ios_base::cur:
+                if (in) {
+                    noff = gptr() - eback();
+                } else {
+                    noff = pptr() - pbase();
+                }
+                break;
+            case std::ios_base::end:
+                noff = end;
+                break;
+            default:
+                return pos_type(-1);
+        }
+        noff += off;
+        if (noff < 0 ||  noff > end) {
+            return pos_type(-1);
+        }
+
+        if (noff != 0 && ((in && gptr() == nullptr) || (out && pptr() == nullptr))) {
+            return pos_type(-1);
+        }
+
+        if (in) {
+            setg(eback(), eback() + noff, egptr());
+        }
+
+        if (out) {
+            setp(pbase(), epptr());
+            pbump(noff);
+        }
+
+        return pos_type(noff);
+    }
+private:
+    // read only buffer init
+    void init(const CharT *base, size_t size) {
+        setg((char*)base, (char*)base, (char*)(base + size));
+    }
+
+    // read write buffer init
+    void init(CharT *base, size_t size) {
+        setg((char*)base, (char*)base, (char*)(base + size));
+        setp((char*)base, (char*)(base + size));
+    }
+};
+
+// dump binary values
+template <class ForwardIterator>
+void hexdumpToStream(std::ostream &os, const ForwardIterator &first, const ForwardIterator &last) {
+    static_assert(
+            std::is_convertible<
+                typename std::iterator_traits<ForwardIterator>::iterator_category,
+                std::forward_iterator_tag>::value
+            && std::is_convertible<
+                typename std::iterator_traits<ForwardIterator>::value_type,
+                unsigned char>::value
+            && sizeof(typename std::iterator_traits<ForwardIterator>::value_type)
+                == sizeof(unsigned char),
+            "Only accepts forward iterator of a type of size 1 "
+                "that can be convert to unsigned char.\n");
+    size_t c = 0;
+    std::ostringstream ss;
+    for (ForwardIterator i = first; i != last; ++i, ++c) {
+        unsigned char v = *i;
+        // formatting
+        switch (c & 0xf) {
+            case 0:
+                // address
+                os << ss.str() << LOG_ENDL;
+                ss.str("");
+                ss << std::hex;
+                ss << std::setfill('0') << std::setw(4) << c << ": ";
+                break;
+            case 8:
+                // space
+                ss << " ";
+                break;
+        }
+        ss << std::setfill('0') << std::setw(2)
+           << static_cast<unsigned>(static_cast<unsigned char>(v)) << " ";
+    }
+    os << ss.str() << LOG_ENDL;
+}
+} //namespace HidUtil
+
+#endif // HIDUTIL_STREAM_IO_UTIL_H_
+
diff --git a/modules/sensors/dynamic_sensor/HidUtils/TriState.h b/modules/sensors/dynamic_sensor/HidUtils/TriState.h
new file mode 100644
index 0000000..1e44826
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/TriState.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_TRISTATE_H_
+#define HIDUTIL_TRISTATE_H_
+
+#include <cassert>
+#include <iostream>
+
+namespace HidUtil {
+template<typename T>
+class TriState {
+public:
+    // constructor
+    TriState() : mIsSet(false) { }
+    TriState(const TriState<T> &other) : mIsSet(other.mIsSet), mValue(other.mValue) { }
+    explicit TriState(const T &value) : mIsSet(true), mValue(value) { }
+
+    void clear() {
+        mValue = T();
+        mIsSet = false;
+    }
+    bool isSet() const {
+        return mIsSet;
+    }
+
+    const T get(const T &defaultValue) const {
+        return isSet() ? mValue : defaultValue;
+    }
+
+    // operator overloading
+    explicit operator T () const {
+        assert(mIsSet);
+        return mValue;
+    }
+
+    TriState<T>& operator=(const TriState<T> &other) {
+        mIsSet = other.mIsSet;
+        mValue = other.mValue;
+        return *this;
+    }
+
+    TriState<T>& operator=(const T& value) {
+        mIsSet = true;
+        mValue = value;
+        return *this;
+    }
+
+    TriState<T>& operator++()  {
+        if (mIsSet) {
+            mValue++;
+        }
+        return *this;
+    }
+
+    TriState<T> operator++(int) {
+        TriState<T> tmp(*this);
+        operator++();
+        return tmp;
+    }
+
+    TriState<T>& operator--()  {
+        if (mIsSet) {
+            mValue--;
+        }
+        return *this;
+    }
+
+    TriState<T> operator--(int) {
+        TriState<T> tmp(*this);
+        operator--();
+        return tmp;
+    }
+
+#define UNARY_OP(op) \
+    TriState<T> operator op() { \
+        TriState<T> tmp(*this); \
+        if (mIsSet) { \
+            tmp.mValue = op tmp.mValue; \
+        } \
+        return tmp; \
+    }
+
+    UNARY_OP(!);
+    UNARY_OP(-);
+    UNARY_OP(~);
+#undef UNARY_OP
+
+#define COMPOUND_ASSIGN_OP(op) \
+    TriState<T>& operator op (const TriState<T>& rhs) { \
+        if (mIsSet && rhs.mIsSet) { \
+            mValue op rhs.mValue; \
+        } else { \
+            mIsSet = false; \
+        } \
+        return *this; \
+    } \
+    TriState<T>& operator op(const T& rhs) { \
+        if (mIsSet) { \
+            mValue op rhs; \
+        } \
+        return *this; \
+    }
+
+    COMPOUND_ASSIGN_OP(+=);
+    COMPOUND_ASSIGN_OP(-=);
+    COMPOUND_ASSIGN_OP(*=);
+    COMPOUND_ASSIGN_OP(/=);
+    COMPOUND_ASSIGN_OP(%=);
+    COMPOUND_ASSIGN_OP(&=);
+    COMPOUND_ASSIGN_OP(|=);
+    COMPOUND_ASSIGN_OP(^=);
+#undef COMPOUND_ASSIGN_OP
+
+    TriState<T>& operator >>=(int i) {
+        if (mIsSet) {
+            mValue >>= i;
+        }
+        return *this; \
+    }
+
+    TriState<T>& operator <<=(int i) {
+        if (mIsSet) {
+            mValue <<= i;
+        }
+        return *this; \
+    }
+
+    TriState<T> operator <<(int i) { \
+        TriState<T> tmp(*this);
+        operator<<(i);
+        return tmp;
+    }
+
+    TriState<T> operator >>(int i) { \
+        TriState<T> tmp(*this);
+        operator>>(i);
+        return tmp;
+    }
+
+#define BINARY_OP(op, compound_op) \
+    friend TriState<T> operator op(TriState<T> lhs, const TriState<T>& rhs) { \
+        lhs compound_op rhs; \
+    return lhs; \
+    }\
+        friend TriState<T> operator op(TriState<T> lhs, const T& rhs) { \
+    lhs compound_op rhs; \
+        return lhs; \
+    }\
+    friend TriState<T> operator op(const T &lhs, const TriState<T>& rhs) { \
+        TriState<T> tmp(lhs); \
+        return tmp op rhs; \
+    }
+
+    BINARY_OP(+, +=);
+    BINARY_OP(-, -=);
+    BINARY_OP(*, *=);
+    BINARY_OP(/, /=);
+    BINARY_OP(%, %=);
+    BINARY_OP(&, &=);
+    BINARY_OP(|, |=);
+    BINARY_OP(^, ^=);
+#undef BINARY_OP
+
+#define RELATION_OP(op) \
+    friend TriState<bool> operator op(const TriState<T>& lhs, const TriState<T>& rhs) { \
+        if (lhs.mIsSet && rhs.mIsSet) { \
+            return TriState<bool>(lhs.mValue op rhs.mValue); \
+        } else { \
+        return TriState<bool>(); \
+        } \
+    } \
+    friend TriState<bool> operator op(const TriState<T>& lhs, const T& rhs) { \
+        if (lhs.mIsSet) { \
+            return TriState<bool>(lhs.mValue op rhs); \
+        } else { \
+            return TriState<bool>(); \
+        } \
+    } \
+    friend TriState<bool> operator op(const T& lhs, const TriState<T>& rhs) { \
+        if (rhs.mIsSet) { \
+            return TriState<bool>(lhs op rhs.mValue); \
+        } else { \
+            return TriState<bool>(); \
+        } \
+    }
+
+    RELATION_OP(==);
+    RELATION_OP(!=);
+    RELATION_OP(>=);
+    RELATION_OP(<=);
+    RELATION_OP(>);
+    RELATION_OP(<);
+#undef RELATION_OP
+
+    friend TriState<bool> operator &&(TriState<T>& lhs, const TriState<T>& rhs) {
+        if (lhs.mIsSet && rhs.mIsSet) {
+            return TriState<bool>(lhs.mValue && rhs.mValue);
+        } else {
+            return TriState<bool>();
+        }
+    }
+
+    friend TriState<bool> operator ||(TriState<T>& lhs, const TriState<T>& rhs) {
+        if (lhs.mIsSet && rhs.mIsSet) {
+            return TriState<bool>(lhs.mValue || rhs.mValue);
+        } else {
+            return TriState<bool>();
+        }
+    }
+
+    friend std::ostream& operator <<(std::ostream &os, const TriState<T> &v) {
+        if (v.mIsSet) {
+            os << v.mValue;
+        } else {
+            os << "[not set]";
+        }
+        return os;
+    }
+
+    friend std::istream& operator >>(std::istream &is, const TriState<T> &v) {
+        T a;
+        is >> a;
+        v = TriState<T>(a);
+        return is;
+    }
+private:
+    bool mIsSet;
+    T mValue;
+};
+
+// commonly used ones
+typedef TriState<unsigned> tri_uint;
+typedef TriState<int> tri_int;
+
+typedef TriState<uint32_t> tri_uint32_t;
+typedef TriState<int32_t> tri_int32_t;
+typedef TriState<uint8_t> tri_uint8_t;
+typedef TriState<uint16_t> tri_uint16_t;
+}
+
+#endif // HIDUTIL_TRISTATE_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample.cpp
new file mode 100644
index 0000000..ec7243e
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidLog.h"
+#include "HidParser.h"
+#include "TestHidDescriptor.h"
+#include <errno.h>
+
+using HidUtil::HidParser;
+
+bool doParse() {
+    HidParser hidParser;
+    bool ret = true;
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        const char *name = p->name != nullptr ? p->name : "unnamed";
+        bool parseResult = hidParser.parse(p->data, p->len);
+
+        if (parseResult) {
+            LOG_V << name << "  filtered tree: " << LOG_ENDL;
+            LOG_V << *(hidParser.getTree());
+        } else {
+            ret = false;
+            LOG_E << name << " parsing error!" << LOG_ENDL;
+        }
+    }
+    return ret;
+}
+
+bool doParseAndFilter() {
+    HidParser hidParser;
+    bool ret = true;
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        const char *name = p->name != nullptr ? p->name : "unnamed";
+        bool parseResult = hidParser.parse(p->data, p->len);
+
+        if (parseResult) {
+            hidParser.filterTree();
+            LOG_V << name << "  filtered tree: " << LOG_ENDL;
+            LOG_V << *(hidParser.getTree());
+        } else {
+            ret = false;
+            LOG_E << name << " parsing error!" << LOG_ENDL;
+        }
+    }
+    return ret;
+}
+
+bool doDigest() {
+    HidParser hidParser;
+    bool ret = true;
+
+    // value from HID sensor usage page spec
+    std::unordered_set<unsigned int> interestedUsage = {
+        0x200073, // accelerometer 3d
+        0x200076, // gyro 3d
+        0x200083, // mag 3d
+        0x20008a, // device orientation (rotation vector)
+    };
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        const char *name = p->name != nullptr ? p->name : "unnamed";
+        bool parseResult = hidParser.parse(p->data, p->len);
+
+        if (!parseResult) {
+            LOG_E << name << " parsing error!" << LOG_ENDL;
+            ret = false;
+            continue;
+        }
+
+        hidParser.filterTree();
+        LOG_V << name << "  digest: " << LOG_ENDL;
+        HidParser::DigestVector digestVector = hidParser.generateDigest(interestedUsage);
+        LOG_V << digestVector;
+    }
+    return ret;
+}
+
+void printUsage(char *argv0) {
+    LOG_V << "Usage: " << argv0 << " test_name" << LOG_ENDL;
+    LOG_V << "  test_name can be parse, parse_filter, digest." << LOG_ENDL;
+}
+
+int main(int argc, char* argv[]) {
+    int ret;
+
+    if (argc != 2) {
+        LOG_E << "Error: need param" << LOG_ENDL;
+        printUsage(argv[0]);
+        return -EINVAL;
+    }
+
+    if (strcmp(argv[1], "parse") == 0) {
+        ret = doParse() ? 0 : 1;
+    } else if (strcmp(argv[1], "parse_filter") == 0) {
+        ret = doParseAndFilter() ? 0 : 1;
+    } else if (strcmp(argv[1], "digest") == 0) {
+        ret = doDigest() ? 0 : 1;
+    } else {
+        LOG_E << "Error: unknown test name" << LOG_ENDL;
+        printUsage(argv[0]);
+        ret = -ENOENT;
+    }
+
+    return ret;
+}
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample2.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample2.cpp
new file mode 100644
index 0000000..b151dff
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample2.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TestHidDescriptor.h"
+#include "HidLog.h"
+#include "HidParser.h"
+#include "StreamIoUtil.h"
+
+using namespace HidUtil;
+
+void printRawValue(const std::vector<unsigned char> &descriptor) {
+    LOG_D << "Descriptor [" << descriptor.size() << "]: " << std::hex;
+    hexdumpToStream(LOG_D, descriptor.begin(), descriptor.end());
+}
+
+void printToken(const std::vector<HidItem> &hidItemVector) {
+    LOG_V << "Total " << hidItemVector.size() << " tokens" << LOG_ENDL;
+    for (auto &i : hidItemVector) {
+        LOG_V << i << LOG_ENDL;
+    }
+}
+
+int main() {
+    const TestHidDescriptor *t = findTestDescriptor("accel3");
+    constexpr unsigned int ACCEL_3D_USAGE = 0x200073;
+
+    assert(t != nullptr);
+    std::vector<unsigned char> descriptor(t->data, t->data + t->len);
+
+    // parse can be done in one step with HidParser::parse(const unsigned char *begin, size_t size);
+    // here it is done in multiple steps for illustration purpose
+    HidParser hidParser;
+    // print out raw value
+    printRawValue(descriptor);
+
+    // tokenize it
+    std::vector<HidItem> hidItemVector = HidItem::tokenize(descriptor);
+
+    // print out tokens
+    printToken(hidItemVector);
+
+    // parse it
+    if (hidParser.parse(hidItemVector)) {
+        // making a deepcopy of tree (not necessary, but for illustration)
+        std::shared_ptr<HidTreeNode> tree = hidParser.getTree()->deepCopy();
+
+        LOG_V << "Tree: " << LOG_ENDL;
+        LOG_V << *tree;
+        LOG_V << LOG_ENDL;
+
+        hidParser.filterTree();
+        LOG_V << "FilteredTree: " << LOG_ENDL;
+        LOG_V << *(hidParser.getTree());
+
+        LOG_V << "DigestVector: " << LOG_ENDL;
+        std::unordered_set<unsigned int> interested = {ACCEL_3D_USAGE};
+        HidParser::DigestVector digestVector = hidParser.generateDigest(interested);
+        LOG_V << digestVector;
+
+    } else {
+        LOG_V << "Parsing Error" << LOG_ENDL;
+    }
+
+    return 0;
+}
+
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.cpp
new file mode 100644
index 0000000..ac57d4f
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.cpp
@@ -0,0 +1,2607 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "TestHidDescriptor.h"
+#include "TestHidSensorSpec.h"
+#include <cstring>
+
+/**
+ * Example HID sensor descriptors in this file is extracted from published document
+ * "HID Sensors Usage" (hid-sensors-usage.docx). They are added for testing of HidParser.
+ *
+ * It is slightly modified in order to compile.
+ */
+namespace {
+/**
+ * Two sensors collection skeleton example.
+ */
+const unsigned char col1_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_COLLECTION,
+    HID_COLLECTION(Application),
+
+    HID_REPORT_ID(1),
+    HID_USAGE_PAGE_SENSOR,
+
+    HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 1
+
+    //Input Report Descriptor for Sensor Report ID = 1
+
+    HID_END_COLLECTION, //for Report ID = 1
+
+    HID_REPORT_ID(2),
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 2
+
+    //Input Report Descriptor for Sensor Report ID = 2
+
+    HID_END_COLLECTION, //for Report ID = 2
+
+    //More sensors follow using the same pattern
+
+    HID_END_COLLECTION //Application
+};
+
+
+/**
+ * Composite device descriptor example: two sensors with a keyboard and a mouse.
+ */
+const unsigned char col2_report_descriptor[] = {
+    //keyboard
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x06U,         // USAGE (Keyboard)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+
+    0x85U, 0x03U,         // REPORT_ID (1)
+
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x95U, 0x08U,         //   REPORT COUNT (8)
+    0x05U, 0x07U,         //   USAGE PAGE (Keyboard)
+    0x19U, 0xE0U,         //   USAGE MINIMUM (Keyboard LeftControl)
+    0x29U, 0xE7U,         //   USAGE MAXIMUM (Keyboard Right GUI)
+    0x81U, 0x02U,         //   INPUT (Var)
+
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x0AU,         //   REPORT COUNT (10)
+    0x19U, 0x00U,         //   USAGE MINIMUM (No event)
+    0x29U, 0x91U,         //   USAGE MAXIMUM (Keyboard LANG2)
+    0x26U, 0xFFU, 0x00U,  //   LOGICAL MAXIMUM (0xFF)
+    0x81U, 0x00U,         //   INPUT (Data,Ary,Abs)
+
+    0xC0U,                // END COLLECTION, //keyboard
+
+    // Two sensor collection skeleton example:
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_COLLECTION,
+    HID_COLLECTION(Application),
+
+    HID_REPORT_ID(2),
+    HID_USAGE_PAGE_SENSOR,
+
+    HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 2
+
+    //Input Report Descriptor for Sensor Report ID = 2
+
+    HID_END_COLLECTION, //for Report ID = 2
+
+    HID_REPORT_ID(3),
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 3
+
+    //Input Report Descriptor for Sensor Report ID = 3
+
+    HID_END_COLLECTION, //for Report ID = 3
+
+    //More sensors follow using the same pattern
+
+    HID_END_COLLECTION, //Sensor collection
+
+    //mouse
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x02U,         // USAGE (Mouse)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+    0x85U, 0x04U,         // REPORT_ID (4)
+
+    // 5 mouse buttons
+    0x05U, 0x09U,         //   USAGE PAGE (Button)
+    0x19U, 0x01U,         //   USAGE MINIMUM (Button 1)
+    0x29U, 0x05U,         //   USAGE MAXIMUM (Button 5)
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x95U, 0x05U,         //   REPORT COUNT (5)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x81U, 0x02U,         //   INPUT (Data,Var,Abs)
+
+    //  3 unused buttons:
+    0x95U, 0x01U,         //   REPORT COUNT (1)
+    0x75U, 0x03U,         //   REPORT SIZE (3)
+    0x81U, 0x03U,         //   INPUT (Cnst,Var,Abs)
+
+    // mouse (delta x, delta y) position
+    0x15U, 0x81U,         //   LOGICAL MINIMUM (-127)
+    0x25U, 0x7fU,         //   LOGICAL MAXIMUM (+127)
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x02U,         //   REPORT COUNT (2)
+    0x05U, 0x01U,         //   USAGE PAGE (Generic Desktop)
+    0x09U, 0x30U,         //   USAGE(X)
+    0x09U, 0x31U,         //   USAGE (Y)
+    0x81U, 0x06U,         //   INPUT (Data,Var,Rel)
+
+    0xC0U,                // END COLLECTION //mouse
+};
+
+
+/**
+ * Composite device descriptor example: one sensor with a keyboard and a mouse.
+ */
+const unsigned char col3_report_descriptor[] = {
+    //keyboard
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x06U,         // USAGE (Keyboard)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+
+    0x85U, 0x03U,         // REPORT_ID (1)
+
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x95U, 0x08U,         //   REPORT COUNT (8)
+    0x05U, 0x07U,         //   USAGE PAGE (Keyboard)
+    0x19U, 0xE0U,         //   USAGE MINIMUM (Keyboard LeftControl)
+    0x29U, 0xE7U,         //   USAGE MAXIMUM (Keyboard Right GUI)
+    0x81U, 0x02U,         //   INPUT (Var)
+
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x0AU,         //   REPORT COUNT (10)
+    0x19U, 0x00U,         //   USAGE MINIMUM (No event)
+    0x29U, 0x91U,         //   USAGE MAXIMUM (Keyboard LANG2)
+    0x26U, 0xFFU, 0x00U,  //   LOGICAL MAXIMUM (0xFF)
+    0x81U, 0x00U,         //   INPUT (Data,Ary,Abs)
+
+    0xC0U,                // END COLLECTION, //keyboard
+
+    // One sensor collection skeleton example:
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_COLLECTION,
+    HID_COLLECTION(Application),
+
+    HID_REPORT_ID(2),
+    HID_USAGE_PAGE_SENSOR,
+
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 2
+
+    //Input Report Descriptor for Sensor Report ID = 2
+
+    HID_END_COLLECTION, //for Report ID = 2
+
+    HID_END_COLLECTION, //Sensor collection
+
+    //mouse
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x02U,         // USAGE (Mouse)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+    0x85U, 0x04U,         // REPORT_ID (3)
+
+    // 5 mouse buttons
+    0x05U, 0x09U,         //   USAGE PAGE (Button)
+    0x19U, 0x01U,         //   USAGE MINIMUM (Button 1)
+    0x29U, 0x05U,         //   USAGE MAXIMUM (Button 5)
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x95U, 0x05U,         //   REPORT COUNT (5)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x81U, 0x02U,         //   INPUT (Data,Var,Abs)
+
+    //  3 unused buttons:
+    0x95U, 0x01U,         //   REPORT COUNT (1)
+    0x75U, 0x03U,         //   REPORT SIZE (3)
+    0x81U, 0x03U,         //   INPUT (Cnst,Var,Abs)
+
+    // mouse (delta x, delta y) position
+    0x15U, 0x81U,         //   LOGICAL MINIMUM (-127)
+    0x25U, 0x7fU,         //   LOGICAL MAXIMUM (+127)
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x02U,         //   REPORT COUNT (2)
+    0x05U, 0x01U,         //   USAGE PAGE (Generic Desktop)
+    0x09U, 0x30U,         //   USAGE(X)
+    0x09U, 0x31U,         //   USAGE (Y)
+    0x81U, 0x06U,         //   INPUT (Data,Var,Rel)
+
+    0xC0U,                 //   END COLLECTION //mouse
+};
+
+
+/**
+ * Simple custom sensor example.
+ */
+const unsigned char cus1_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Physical),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * More complex custom sensor example.
+ */
+const unsigned char cus2_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Physical),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_DATA_CUSTOM_USAGE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER
+    HID_USAGE_SENSOR_DATA_CUSTOM_BOOLEAN_ARRAY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_4,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_5,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_6,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Custom sensor example with features
+ */
+const unsigned char cus3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_CUSTOM_USAGE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Full custom sensor example with feature.
+ */
+const unsigned char cus4_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Application),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_CUSTOM_USAGE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_BOOLEAN_ARRAY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_4,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_5,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_6,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+#if 1 //define vendor-specific (non-spec) custom datafields
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_7,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_8,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_9,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_10,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_11,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_12,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_13,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_14,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_15,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_16,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_17,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_18,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_19,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_20,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_21,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_22,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_23,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_24,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_25,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_26,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_27,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_28,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+#endif
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Human presence sensor example.
+ */
+const unsigned char pres_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_BIOMETRIC_PRESENCE,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PRESENCE,
+    HID_LOGICAL_MIN_8(0), // False
+    HID_LOGICAL_MAX_8(1), // True
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Proximity sensor example.
+ */
+const unsigned char prox_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_BIOMETRIC_PROXIMITY,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_OUT_OF_RANGE,
+    HID_LOGICAL_MIN_8(0), // False
+    HID_LOGICAL_MAX_8(1), // True
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D),  // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Barometer sensor example.
+ */
+const unsigned char bar_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Humidity sensor example.
+ */
+const unsigned char humi_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_HUMIDITY,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "percent"
+    // to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Temperature sensor example.
+ */
+const unsigned char temp_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_TEMPERATURE,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(16),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Ambient light sensor example.
+ */
+const unsigned char als_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_LIGHT_AMBIENTLIGHT, // USAGE (AmbientLight)
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_REL_PCT),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //add this definition if required by the specific application
+    HID_USAGE_SENSOR_PROPERTY_RESPONSE_CURVE,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(10), //as required for n pair of values
+    HID_UNIT_EXPONENT(0x0), // scale default unit to provide 0 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_LIGHT_COLOR_TEMPERATURE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_X,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0x0C), // scale default unit to provide 4 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_Y,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0x0C), // scale default unit to provide 4 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D accelerometer sensor example.
+ */
+const unsigned char accel3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_X_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Y_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Z_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    //include the following datafield if required to support the “shake” event
+    HID_USAGE_SENSOR_DATA_MOTION_STATE,
+    HID_LOGICAL_MIN_8(0), // False = Still
+    HID_LOGICAL_MAX_8(1), // True = In Motion
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D gyroscope sensor example.
+ */
+const unsigned char gyro3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_X_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Y_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Z_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D compass sensor example.
+ */
+const unsigned char comp3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_MAGNETIC_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_TRUE_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TRUE_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_X_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit to "milliGauss"
+    // to provide 3 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Y_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit to "milliGauss"
+    // to provide 3 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Z_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit to "milliGauss"
+    // to provide 3 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D inclinomater example.
+ */
+const unsigned char inc3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_TILT,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_TILT,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_TILT,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_X,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Y,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Z,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Device orientation sensor example. Note this maps to rotation vector sensor in android.
+ */
+const unsigned char devor_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ORIENTATION_DEVICE_ORIENTATION,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "meter" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x01),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x01),
+    HID_FEATURE(Data_Var_Abs),
+
+    //include this if the values are calculated in firmware
+    //otherwise, the driver will calculate these values from the Quaternion
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(4),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_INPUT(Data_Arr_Abs),
+
+    //include this if the values are calculated in firmware
+    //otherwise, the driver will calculate these values from the Quaternion
+    HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(9),
+    HID_UNIT_EXPONENT(0x0F),
+    HID_INPUT(Data_Arr_Abs),
+
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+
+    HID_END_COLLECTION
+};
+} // annoymous namespace
+
+/**
+ * Global test vector entry.
+ */
+#define TEST_DESCRIPTOR(name) \
+    { name ## _report_descriptor, sizeof(name ## _report_descriptor), #name }
+
+const TestHidDescriptor gDescriptorArray[] = {
+    TEST_DESCRIPTOR(accel3),
+    TEST_DESCRIPTOR(col1),
+    TEST_DESCRIPTOR(col2),
+    TEST_DESCRIPTOR(col3),
+    TEST_DESCRIPTOR(cus1),
+    TEST_DESCRIPTOR(cus2),
+    TEST_DESCRIPTOR(cus3),
+    TEST_DESCRIPTOR(cus4),
+    TEST_DESCRIPTOR(pres),
+    TEST_DESCRIPTOR(prox),
+    TEST_DESCRIPTOR(bar),
+    TEST_DESCRIPTOR(humi),
+    TEST_DESCRIPTOR(temp),
+    TEST_DESCRIPTOR(als),
+    TEST_DESCRIPTOR(gyro3),
+    TEST_DESCRIPTOR(comp3),
+    TEST_DESCRIPTOR(inc3),
+    TEST_DESCRIPTOR(devor),
+    {nullptr, 0, nullptr} //sentinel
+};
+#undef TEST_DESCRIPTOR
+
+const TestHidDescriptor *findTestDescriptor(const char *name) {
+    if (name == nullptr) {
+        return nullptr;
+    }
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        if (strcmp(p->name, name) == 0) {
+            return p;
+        }
+    }
+    return nullptr;
+}
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.h b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.h
new file mode 100644
index 0000000..417cb72
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_TEST_HIDDESCRIPTOR_H_
+#define HIDUTIL_TEST_HIDDESCRIPTOR_H_
+
+#include <cstddef>
+
+struct TestHidDescriptor {
+    const unsigned char *data;
+    size_t len;
+    const char *name;
+};
+
+extern const TestHidDescriptor gDescriptorArray[];
+const TestHidDescriptor *findTestDescriptor(const char *name);
+
+#endif // HIDUTIL_TEST_HIDDESCRIPTOR_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TestHidSensorSpec.h b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidSensorSpec.h
new file mode 100644
index 0000000..522cb6c
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidSensorSpec.h
@@ -0,0 +1,859 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_TEST_HIDSENSORSPEC_H
+#define HIDUTIL_TEST_HIDSENSORSPEC_H
+/**
+ * Example HID sensor definition in from published document "HID Sensors Usage"
+ * (hid-sensors-usage.docx). This file is added as part of the test case.
+ *
+ * It is slightly modified in order to compile.
+ */
+#define HID_USAGE_PAGE_SENSOR                                                           0x05,0x20
+
+//sensor category usages
+#define HID_USAGE_SENSOR_TYPE_COLLECTION                                                0x09,0x01
+//sensor category biometric
+#define HID_USAGE_SENSOR_CATEGORY_BIOMETRIC                                             0x09,0x10
+#define HID_USAGE_SENSOR_TYPE_BIOMETRIC_PRESENCE                                        0x09,0x11
+#define HID_USAGE_SENSOR_TYPE_BIOMETRIC_PROXIMITY                                       0x09,0x12
+#define HID_USAGE_SENSOR_TYPE_BIOMETRIC_TOUCH                                           0x09,0x13
+//sensor category electrical
+#define HID_USAGE_SENSOR_CATEGORY_ELECTRICAL                                            0x09,0x20
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_CAPACITANCE                                    0x09,0x21
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_CURRENT                                        0x09,0x22
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_POWER                                          0x09,0x23
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_INDUCTANCE                                     0x09,0x24
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_RESISTANCE                                     0x09,0x25
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_VOLTAGE                                        0x09,0x26
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_POTENTIOMETER                                  0x09,0x27
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_FREQUENCY                                      0x09,0x28
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_PERIOD                                         0x09,0x29
+//sensor category environmental
+#define HID_USAGE_SENSOR_CATEGORY_ENVIRONMENTAL                                         0x09,0x30
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE                        0x09,0x31
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_HUMIDITY                                    0x09,0x32
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_TEMPERATURE                                 0x09,0x33
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_WIND_DIRECTION                              0x09,0x34
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_WIND_SPEED                                  0x09,0x35
+//sensor category light
+#define HID_USAGE_SENSOR_CATEGORY_LIGHT                                                 0x09,0x40
+#define HID_USAGE_SENSOR_TYPE_LIGHT_AMBIENTLIGHT                                        0x09,0x41
+#define HID_USAGE_SENSOR_TYPE_LIGHT_CONSUMER_INFRARED                                   0x09,0x42
+//sensor category location
+#define HID_USAGE_SENSOR_CATEGORY_LOCATION                                              0x09,0x50
+#define HID_USAGE_SENSOR_TYPE_LOCATION_BROADCAST                                        0x09,0x51
+#define HID_USAGE_SENSOR_TYPE_LOCATION_DEAD_RECKONING                                   0x09,0x52
+#define HID_USAGE_SENSOR_TYPE_LOCATION_GPS                                              0x09,0x53
+#define HID_USAGE_SENSOR_TYPE_LOCATION_LOOKUP                                           0x09,0x54
+#define HID_USAGE_SENSOR_TYPE_LOCATION_OTHER                                            0x09,0x55
+#define HID_USAGE_SENSOR_TYPE_LOCATION_STATIC                                           0x09,0x56
+#define HID_USAGE_SENSOR_TYPE_LOCATION_TRIANGULATION                                    0x09,0x57
+//sensor category mechanical
+#define HID_USAGE_SENSOR_CATEGORY_MECHANICAL                                            0x09,0x60
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_BOOLEAN_SWITCH                                 0x09,0x61
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_BOOLEAN_SWITCH_ARRAY                           0x09,0x62
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_MULTIVALUE_SWITCH                              0x09,0x63
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_FORCE                                          0x09,0x64
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_PRESSURE                                       0x09,0x65
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_STRAIN                                         0x09,0x66
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_SCALE_WEIGHT                                   0x09,0x67
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_VIBRATOR                                       0x09,0x68
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_HALL_EFFECT_SWITCH                             0x09,0x69
+//sensor category motion
+#define HID_USAGE_SENSOR_CATEGORY_MOTION                                                0x09,0x70
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_1D                                   0x09,0x71
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_2D                                   0x09,0x72
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D                                   0x09,0x73
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_1D                                       0x09,0x74
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_2D                                       0x09,0x75
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D                                       0x09,0x76
+#define HID_USAGE_SENSOR_TYPE_MOTION_MOTION_DETECTOR                                    0x09,0x77
+#define HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER                                        0x09,0x78
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER                                      0x09,0x79
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER                                          0x09,0x7A
+//sensor category orientation
+#define HID_USAGE_SENSOR_CATEGORY_ORIENTATION                                           0x09,0x80
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_1D                                    0x09,0x81
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_2D                                    0x09,0x82
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_3D                                    0x09,0x83
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_1D                               0x09,0x84
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_2D                               0x09,0x85
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_3D                               0x09,0x86
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE_1D                                   0x09,0x87
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE_2D                                   0x09,0x88
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE_3D                                   0x09,0x89
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DEVICE_ORIENTATION                            0x09,0x8A
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS                                       0x09,0x8B
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER                                  0x09,0x8C
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE                                      0x09,0x8D
+//sensor category scanner
+#define HID_USAGE_SENSOR_CATEGORY_SCANNER                                               0x09,0x90
+#define HID_USAGE_SENSOR_TYPE_SCANNER_BARCODE                                           0x09,0x91
+#define HID_USAGE_SENSOR_TYPE_SCANNER_RFID                                              0x09,0x92
+#define HID_USAGE_SENSOR_TYPE_SCANNER_NFC                                               0x09,0x93
+//sensor category time
+#define HID_USAGE_SENSOR_CATEGORY_TIME                                                  0x09,0xA0
+#define HID_USAGE_SENSOR_TYPE_TIME_ALARM                                                0x09,0xA1
+#define HID_USAGE_SENSOR_TYPE_TIME_RTC                                                  0x09,0xA2
+//sensor category other
+#define HID_USAGE_SENSOR_CATEGORY_OTHER                                                 0x09,0xE0
+#define HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM                                              0x09,0xE1
+#define HID_USAGE_SENSOR_TYPE_OTHER_GENERIC                                             0x09,0xE2
+#define HID_USAGE_SENSOR_TYPE_OTHER_GENERIC_ENUMERATOR                                  0x09,0xE3
+
+//unit usages
+#define HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED                                            0x65,0x00                // Unit
+#define HID_USAGE_SENSOR_UNITS_LUX                                                      0x67,0xE1,0x00,0x00,0x01 // Unit
+#define HID_USAGE_SENSOR_UNITS_KELVIN                                                   0x67,0x01,0x00,0x01,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_FAHRENHEIT                                               0x67,0x03,0x00,0x01,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_PASCAL                                                   0x66,0xF1,0xE1           // Unit
+#define HID_USAGE_SENSOR_UNITS_NEWTON                                                   0x66,0x11,0xE1           // Unit
+#define HID_USAGE_SENSOR_UNITS_METERS_PER_SECOND                                        0x66,0x11,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD                                      0x66,0x11,0xE0           // Unit
+#define HID_USAGE_SENSOR_UNITS_FARAD                                                    0x67,0xE1,0x4F,0x20,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_AMPERE                                                   0x67,0x01,0x00,0x10,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_WATT                                                     0x66,0x21,0xD1           // Unit
+#define HID_USAGE_SENSOR_UNITS_HENRY                                                    0x67,0x21,0xE1,0xE0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_OHM                                                      0x67,0x21,0xD1,0xE0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_VOLT                                                     0x67,0x21,0xD1,0xF0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_HERTZ                                                    0x66,0x01,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_DEGREES                                                  0x65,0x14                // Unit
+#define HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND                                       0x66,0x14,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_DEGREES_PER_SEC_SQRD                                     0x66,0x14,0xE0           // Unit
+#define HID_USAGE_SENSOR_UNITS_RADIANS                                                  0x65,0x12                // Unit
+#define HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND                                       0x66,0x12,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_RADIANS_PER_SEC_SQRD                                     0x66,0x12,0xE0           // Unit
+#define HID_USAGE_SENSOR_UNITS_SECOND                                                   0x66,0x01,0x10           // Unit
+#define HID_USAGE_SENSOR_UNITS_GAUSS                                                    0x67,0x01,0xE1,0xF0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_GRAM                                                     0x66,0x01,0x01           // Unit
+#define HID_USAGE_SENSOR_UNITS_CENTIMETER                                               0x65,0x11                // Unit
+#ifdef DEFINE_NON_HID_UNITS
+#define HID_USAGE_SENSOR_UNITS_CELSIUS              "Use Unit(Kelvin) and subtract 273.15"
+#define HID_USAGE_SENSOR_UNITS_KILOGRAM             "Use Unit(gram) and UnitExponent(0x03)"
+#define HID_USAGE_SENSOR_UNITS_METER                "Use Unit(centimeter) and UnitExponent(0x02)"
+#define HID_USAGE_SENSOR_UNITS_BAR                  "Use Unit(Pascal) and UnitExponent(0x05)"
+#define HID_USAGE_SENSOR_UNITS_KNOT                 "Use Unit(m/s) and multiply by 1852/3600"
+#define HID_USAGE_SENSOR_UNITS_PERCENT              "Use Unit(Not_Specified)"
+#define HID_USAGE_SENSOR_UNITS_G                    "Use Unit(m/s2) and divide by 9.8"
+#define HID_USAGE_SENSOR_UNITS_MILLISECOND          "Use Unit(second) and UnitExponent(0x0D)"
+#define HID_USAGE_SENSOR_UNITS_MILLIGAUSS           "Use Unit(Gauss) and UnitExponent(0x0D)"
+#endif
+//unit deprecated usages
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_LUX                                           0x01
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_KELVIN                                        0x02
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_CELSIUS                                       0x03
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_PASCAL                                        0x04
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_NEWTON                                        0x05
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_METERS_PER_SECOND                             0x06
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_KILOGRAM                                      0x07
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_METER                                         0x08
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_METERS_PER_SEC_SQRD                           0x09
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_FARAD                                         0x0A
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_AMPERE                                        0x0B
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_WATT                                          0x0C
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_HENRY                                         0x0D
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_OHM                                           0x0E
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_VOLT                                          0x0F
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_HERTZ                                         0x10
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_BAR                                           0x11
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREES_ANTI_CLOCKWISE                        0x12
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREES_CLOCKWISE                             0x13
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREE                                        0x14
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREES_PER_SECOND                            0x15
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_KNOT                                          0x16
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_PERCENT                                       0x17
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_SECOND                                        0x18
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_MILLISECOND                                   0x19
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_G                                             0x1A
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_BYTES                                         0x1B
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_MILLIGAUSS                                    0x1C
+
+//data type usage modifiers -- we use them as modifiers for sensor properties & data fields
+//to create thresholds, for example.
+//NOTE: the usage tables actually define these as two bytes, but in order
+//to get the define macros to work so these are ‘or-ed’ these are defined
+//here as only one byte.
+#define HID_USAGE_SENSOR_DATA_MOD_NONE                                                  0x00 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS                                0x10 // US
+#define HID_USAGE_SENSOR_DATA_MOD_MAX                                                   0x20 // US
+#define HID_USAGE_SENSOR_DATA_MOD_MIN                                                   0x30 // US
+#define HID_USAGE_SENSOR_DATA_MOD_ACCURACY                                              0x40 // US
+#define HID_USAGE_SENSOR_DATA_MOD_RESOLUTION                                            0x50 // US
+#define HID_USAGE_SENSOR_DATA_MOD_THRESHOLD_HIGH                                        0x60 // US
+#define HID_USAGE_SENSOR_DATA_MOD_THRESHOLD_LOW                                         0x70 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CALIBRATION_OFFSET                                    0x80 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CALIBRATION_MULTIPLIER                                0x90 // US
+#define HID_USAGE_SENSOR_DATA_MOD_REPORT_INTERVAL                                       0xA0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_FREQUENCY_MAX                                         0xB0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_PERIOD_MAX                                            0xC0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_RANGE_PCT                          0xD0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_REL_PCT                            0xE0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_VENDOR_RESERVED                                       0xF0 // US
+
+
+//state usages
+#define HID_USAGE_SENSOR_STATE                                                          0x0A,0x01,0x02 // NAry
+//state selectors
+#define HID_USAGE_SENSOR_STATE_UNKNOWN_SEL                                              0x0A,0x00,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_READY_SEL                                                0x0A,0x01,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL                                        0x0A,0x02,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_NO_DATA_SEL                                              0x0A,0x03,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_INITIALIZING_SEL                                         0x0A,0x04,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL                                        0x0A,0x05,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_ERROR_SEL                                                0x0A,0x06,0x08 // Sel
+//state enums
+#define HID_USAGE_SENSOR_STATE_UNKNOWN_ENUM                                             0x01 // Enum
+#define HID_USAGE_SENSOR_STATE_READY_ENUM                                               0x02 // Enum
+#define HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_ENUM                                       0x03 // Enum
+#define HID_USAGE_SENSOR_STATE_NO_DATA_ENUM                                             0x04 // Enum
+#define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM                                        0x05 // Enum
+#define HID_USAGE_SENSOR_STATE_ACCESS_DENIED_ENUM                                       0x06 // Enum
+#define HID_USAGE_SENSOR_STATE_ERROR_ENUM                                               0x07 // Enum
+//state deprecated enums
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_UNKNOWN_ENUM                                  0x00
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_NOT_AVAILABLE_ENUM                            0x01
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_READY_ENUM                                    0x02
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_NO_DATA_ENUM                                  0x03
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_INITIALIZING_ENUM                             0x04
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_ACCESS_DENIED_ENUM                            0x05
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_ERROR_ENUM                                    0x06
+
+//event usages
+#define HID_USAGE_SENSOR_EVENT                                                          0x0A,0x02,0x02 // NAry
+//event selectors
+#define HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL                                              0x0A,0x10,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL                                        0x0A,0x11,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL                                     0x0A,0x12,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL                                         0x0A,0x13,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL                                        0x0A,0x14,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL                                   0x0A,0x15,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_MAX_REACHED_SEL                                          0x0A,0x16,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_MIN_REACHED_SEL                                          0x0A,0x17,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_SEL                          0x0A,0x18,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_HIGH_THESHOLD_CROSS_ABOVE_SEL        HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_SEL                        0x0A,0x19,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_BELOW_SEL       HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_SEL                           0x0A,0x1A,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_ABOVE_SEL        HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_SEL                         0x0A,0x1B,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_BELOW_SEL        HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_SEL                          0x0A,0x1C,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_ABOVE_SEL       HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_SEL                        0x0A,0x1D,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_BELOW_SEL       HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_PERIOD_EXCEEDED_SEL                                      0x0A,0x1E,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_FREQUENCY_EXCEEDED_SEL                                   0x0A,0x1F,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_COMPLEX_TRIGGER_SEL                                      0x0A,0x20,0x08 // Sel
+//event enums
+#define HID_USAGE_SENSOR_EVENT_UNKNOWN_ENUM                                             0x01 // Enum
+#define HID_USAGE_SENSOR_EVENT_STATE_CHANGED_ENUM                                       0x02 // Enum
+#define HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_ENUM                                    0x03 // Enum
+#define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM                                        0x04 // Enum
+#define HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_ENUM                                       0x05 // Enum
+#define HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_ENUM                                  0x06 // Enum
+#define HID_USAGE_SENSOR_EVENT_MAX_REACHED_ENUM                                         0x07 // Enum
+#define HID_USAGE_SENSOR_EVENT_MIN_REACHED_ENUM                                         0x08 // Enum
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_ENUM                         0x09 // Enum
+#define HID_USAGE_SENSOR_EVENT_HIGH_THESHOLD_CROSS_ABOVE_ENUM   HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_ENUM                       0x0A // Enum
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_BELOW_ENUM  HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_ENUM                          0x0B // Enum
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_ABOVE_ENUM   HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_ENUM                        0x0C // Enum
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_BELOW_ENUM   HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_ENUM                         0x0D // Enum
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_ABOVE_ENUM  HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_ENUM                       0x0E // Enum
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_BELOW_ENUM  HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_PERIOD_EXCEEDED_ENUM                                     0x0F // Enum
+#define HID_USAGE_SENSOR_EVENT_FREQUENCY_EXCEEDED_ENUM                                  0x10 // Enum
+#define HID_USAGE_SENSOR_EVENT_COMPLEX_TRIGGER_ENUM                                     0x11 // Enum
+//event deprecated enums
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_UNKNOWN_ENUM                                  0x00
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_STATE_CHANGED_ENUM                            0x01
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_PROPERTY_CHANGED_ENUM                         0x02
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_DATA_UPDATE_ENUM                              0x03
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_POLL_RESPONSE_ENUM                            0x04
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_CHANGE_SENSITIVITY_ENUM                       0x05
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_MAX_REACHED_ENUM                              0x06
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_MIN_REACHED_ENUM                              0x07
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_HIGH_THRESHHOLD_CROSS_ABOVE_ENUM              0x08
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_HIGH_THRESHHOLD_CROSS_BELOW_ENUM              0x09
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_LOW_THRESHHOLD_CROSS_ABOVE_ENUM               0x0A
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_LOW_THRESHHOLD_CROSS_BELOW_ENUM               0x0B
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_ZERO_THRESHOLD_CROSS_ABOVE_ENUM               0x0C
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_ZERO_THRESHOLD_CROSS_BELOW_ENUM               0x0D
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_PERIOD_EXCEEDED_ENUM                          0x0E
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_FREQUENCY_EXCEEDED_ENUM                       0x0F
+
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY                                                       0x0A,0x00,0x03
+#define HID_USAGE_SENSOR_PROPERTY_FRIENDLY_NAME                                         0x0A,0x01,0x03
+#define HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID                                  0x0A,0x02,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS                                         0x0A,0x03,0x03
+#define HID_USAGE_SENSOR_PROPERTY_MINIMUM_REPORT_INTERVAL                               0x0A,0x04,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_MANUFACTURER                                   0x0A,0x05,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_MODEL                                          0x0A,0x06,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_SERIAL_NUMBER                                  0x0A,0x07,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION                                    0x0A,0x08,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE                                0x0A,0x09,0x03 // NAry
+//begin connection type selectors
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL                     0x0A,0x30,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL                       0x0A,0x31,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL                       0x0A,0x32,0x08 // Sel
+//end connection type selectors
+//begin connection type enums
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM                    0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_ENUM                      0x02 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_ENUM                      0x03 // Enum
+//end connection type enums
+//begin connection type deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_CONNECTION_TYPE_PC_INTEGRATED_ENUM         0x00 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_CONNECTION_TYPE_PC_ATTACHED_ENUM           0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_CONNECTION_TYPE_PC_EXTERNAL_ENUM           0x02 // Enum
+//end connection type deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_DEVICE_PATH                                    0x0A,0x0A,0x03
+#define HID_USAGE_SENSOR_PROPERTY_HARDWARE_REVISION                                     0x0A,0x0B,0x03
+#define HID_USAGE_SENSOR_PROPERTY_FIRMWARE_VERSION                                      0x0A,0x0C,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RELEASE_DATE                                          0x0A,0x0D,0x03
+#define HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL                                       0x0A,0x0E,0x03
+#define HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS                                0x0A,0x0F,0x03
+#define HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_RANGE_PCT                          0x0A,0x10,0x03
+#define HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_REL_PCT                            0x0A,0x11,0x03
+#define HID_USAGE_SENSOR_PROPERTY_ACCURACY                                              0x0A,0x12,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RESOLUTION                                            0x0A,0x13,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RANGE_MAXIMUM                                         0x0A,0x14,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RANGE_MINIMUM                                         0x0A,0x15,0x03
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE                                       0x0A,0x16,0x03 // NAry
+//begin reporting state selectors
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL                         0x0A,0x40,0x08 // Sel
+#define HID_USAGE_REPORTING_STATE_ON_NONE_SEL       HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL                        0x0A,0x41,0x08 // Sel
+#define HID_USAGE_REPORTING_STATE_ON_ALL_SEL        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL                  0x0A,0x42,0x08 // Sel
+#define HID_USAGE_REPORTING_STATE_ON_THRESHOLD_SEL  HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL                    0x0A,0x43,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL                   0x0A,0x44,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL             0x0A,0x45,0x08 // Sel
+//end reporting state selectors
+//begin reporting state enums
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_ENUM                        0x01 // Enum
+#define HID_USAGE_REPORTING_STATE_ON_NONE_ENUM      HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_ENUM                       0x02 // Enum
+#define HID_USAGE_REPORTING_STATE_ON_ALL_ENUM       HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_ENUM                 0x03 // Enum
+#define HID_USAGE_REPORTING_STATE_ON_THRESHOLD_ENUM HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL_WAKE_ENUM                   0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL_WAKE_ENUM                  0x05 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_ENUM            0x06 // Enum
+//end reporting state enums
+//begin reporting state deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_NO_EVENTS_ENUM             0x00 // Enum
+#define HID_USAGE_DEPRECATED_REPORTING_STATE_ON_NONE_ENUM      HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_NO_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_ALL_EVENTS_ENUM            0x01 // Enum
+#define HID_USAGE_DEPRECATED_REPORTING_STATE_ON_ALL_ENUM       HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_ALL_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_THRESHOLD_EVENTS_ENUM      0x02 // Enum
+#define HID_USAGE_DEPRECATED_REPORTING_STATE_ON_THRESHOLD_ENUM HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_THRESHOLD_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_NO_EVENTS_WAKE_ENUM        0x03 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_ALL_EVENTS_WAKE_ENUM       0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_ENUM 0x05 // Enum
+//end reporting state deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_SAMPLING_RATE                                         0x0A,0x17,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RESPONSE_CURVE                                        0x0A,0x18,0x03
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE                                           0x0A,0x19,0x03 // NAry
+//begin power state selectors
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL                             0x0A,0x50,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL                         0x0A,0x51,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL                          0x0A,0x52,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL                  0x0A,0x53,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL                    0x0A,0x54,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL                          0x0A,0x55,0x08 // Sel
+//end power state selectors
+//begin power state enums
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_ENUM                            0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_ENUM                        0x02 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_ENUM                         0x03 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_ENUM                 0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_ENUM                   0x05 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_ENUM                         0x06 // Enum
+//end power state enums
+//begin deprecated power state enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_UNDEFINED_ENUM                 0x00 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D0_FULL_POWER_ENUM             0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D1_LOW_POWER_ENUM              0x02 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D2_STANDBY_WITH_WAKE_ENUM      0x03 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D3_SLEEP_WITH_WAKE_ENUM        0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D4_POWER_OFF_ENUM              0x05 // Enum
+//end deprecated power state enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_FEATURE_PAGE_COUNT                         0x0A,0x1A,0x03
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_FEATURE_PAGE_ID                            0x0A,0x1B,0x03
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_INPUT_PAGE_COUNT                           0x0A,0x1C,0x03
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_INPUT_PAGE_ID                              0x0A,0x1D,0x03
+
+//data type location
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_LOCATION                                                  0x0A,0x00,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_DESIRED_ACCURACY                                 0x0A,0x01,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITUDE_ANTENNA_SEALEVEL                        0x0A,0x02,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_DIFFERENTIAL_REFERENCE_STATION_ID                0x0A,0x03,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITIDE_ELIPSOID_ERROR                          0x0A,0x04,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITIDE_ELIPSOID                                0x0A,0x05,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITUDE_SEALEVEL_ERROR                          0x0A,0x06,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITUDE_SEALEVEL                                0x0A,0x07,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_DGPS_DATA_AGE                                    0x0A,0x08,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ERROR_RADIUS                                     0x0A,0x09,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_FIX_QUALITY                                      0x0A,0x0A,0x04 // NAry
+//begin fix quality selectors
+#define HID_USAGE_SENSOR_DATA_FIX_QUALITY_NO_FIX                                        0x0A,0x70,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_QUALITY_GPS                                           0x0A,0x71,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_QUALITY_DGPS                                          0x0A,0x72,0x08 // Sel
+//end fix quality selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_FIX_TYPE                                         0x0A,0x0B,0x04 // NAry
+//begin fix type selectors
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_NO_FIX                                           0x0A,0x80,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_GPS_SPS_MODE_FIX_VALID                           0x0A,0x81,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_DGPS_SPS_MODE_FIX_VALID                          0x0A,0x82,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_GPS_PPS_MODE_FIX_VALID                           0x0A,0x83,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_REAL_TIME_KINEMATIC                              0x0A,0x84,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_FLOAT_RTK                                        0x0A,0x85,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_ESTIMATED_DEAD_RECKONING                         0x0A,0x86,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_MANUAL_INPUT_MODE                                0x0A,0x87,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_SIMULATOR_MODE                                   0x0A,0x88,0x08 // Sel
+//end fix type selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_GEOIDAL_SEPARATION                               0x0A,0x0C,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_GPS_OPERATION_MODE                               0x0A,0x0D,0x04 // NAry
+//begin gps operation mode selectors
+#define HID_USAGE_SENSOR_DATA_GPS_OP_MODE_MANUAL                                        0x0A,0x90,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_OP_MODE_AUTOMATIC                                     0x0A,0x91,0x08 // Sel
+//end gps operation mode selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_GPS_SELECTION_MODE                               0x0A,0x0E,0x04 // NAry
+//begin gps selection mode selectors
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_AUTONOMOUS                                   0x0A,0xA0,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_DGPS                                         0x0A,0xA1,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_ESTIMATED_DEAD_RECKONING                     0x0A,0xA2,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_MANUAL_INPUT                                 0x0A,0xA3,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_SIMULATOR                                    0x0A,0xA4,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_DATA_NOT_VALID                               0x0A,0xA5,0x08 // Sel
+//end gps selection mode selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_GPS_STATUS                                       0x0A,0x0F,0x04 // NAry
+//begin gps status selectors
+#define HID_USAGE_SENSOR_DATA_GPS_STATUS_DATA_VALID                                     0x0A,0xB0,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_STATUS_DATA_NOT_VALID                                 0x0A,0xB1,0x08 // Sel
+//end gps status selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_POSITION_DILUTION_OF_PRECISION                   0x0A,0x10,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_HORIZONTAL_DILUTION_OF_PRECISION                 0x0A,0x11,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_VERTICAL_DILUTION_OF_PRECISION                   0x0A,0x12,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_LATITUDE                                         0x0A,0x13,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_LONGITUDE                                        0x0A,0x14,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_TRUE_HEADING                                     0x0A,0x15,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_MAGNETIC_HEADING                                 0x0A,0x16,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_MAGNETIC_VARIATION                               0x0A,0x17,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SPEED                                            0x0A,0x18,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW                               0x0A,0x19,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_AZIMUTH                       0x0A,0x1A,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_ELEVATION                     0x0A,0x1B,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_ID                            0x0A,0x1C,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_PRNs                          0x0A,0x1D,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_STN_RATIO                     0x0A,0x1E,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_USED_COUNT                            0x0A,0x1F,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_USED_PRNs                             0x0A,0x20,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_NMEA_SENTENCE                                    0x0A,0x21,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ADDRESS_LINE_1                                   0x0A,0x22,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ADDRESS_LINE_2                                   0x0A,0x23,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_CITY                                             0x0A,0x24,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_STATE_OR_PROVINCE                                0x0A,0x25,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_COUNTRY_OR_REGION                                0x0A,0x26,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_POSTAL_CODE                                      0x0A,0x27,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_LOCATION                                              0x0A,0x2A,0x04
+#define HID_USAGE_SENSOR_PROPERTY_LOCATION_DESIRED_ACCURACY                             0x0A,0x2B,0x04 // NAry
+//begin location desired accuracy selectors
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_DEFAULT                                       0x0A,0x60,0x08 // Sel
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_HIGH                                          0x0A,0x61,0x08 // Sel
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_MEDIUM                                        0x0A,0x62,0x08 // Sel
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_LOW                                           0x0A,0x63,0x08 // Sel
+//end location desired accuracy selectors
+
+//data type environmental
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL                                             0x0A,0x30,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE                        0x0A,0x31,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_REFERENCE_PRESSURE                          0x0A,0x32,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY                           0x0A,0x33,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE                                 0x0A,0x34,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_WIND_DIRECTION                              0x0A,0x35,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_WIND_SPEED                                  0x0A,0x36,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_ENVIRONMENTAL                                         0x0A,0x40,0x04
+#define HID_USAGE_SENSOR_PROPERTY_ENVIRONMENTAL_REFERENCE_PRESSURE                      0x0A,0x41,0x04
+
+//data type motion
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_MOTION                                                    0x0A,0x50,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_STATE                                              0x0A,0x51,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION                                       0x0A,0x52,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_X_AXIS                                0x0A,0x53,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Y_AXIS                                0x0A,0x54,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Z_AXIS                                0x0A,0x55,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY                                   0x0A,0x56,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_X_AXIS                            0x0A,0x57,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Y_AXIS                            0x0A,0x58,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Z_AXIS                            0x0A,0x59,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION                                   0x0A,0x5A,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION_X_AXIS                            0x0A,0x5B,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION_Y_AXIS                            0x0A,0x5C,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION_Z_AXIS                            0x0A,0x5D,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_SPEED                                              0x0A,0x5E,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_INTENSITY                                          0x0A,0x5F,0x04
+
+//data type orientation
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_ORIENTATION                                               0x0A,0x70,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING                              0x0A,0x71,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING_X                            0x0A,0x72,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING_Y                            0x0A,0x73,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING_Z                            0x0A,0x74,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_MAGNETIC_NORTH                    0x0A,0x75,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_TRUE_NORTH                        0x0A,0x76,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_NORTH                                0x0A,0x77,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TRUE_NORTH                                    0x0A,0x78,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE                                      0x0A,0x79,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_X                                    0x0A,0x7A,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_Y                                    0x0A,0x7B,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_Z                                    0x0A,0x7C,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_OUT_OF_RANGE                         0x0A,0x7D,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT                                          0x0A,0x7E,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_X                                        0x0A,0x7F,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Y                                        0x0A,0x80,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Z                                        0x0A,0x81,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX                               0x0A,0x82,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION                                    0x0A,0x83,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX                                 0x0A,0x84,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_X_AXIS                          0x0A,0x85,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Y_AXIS                          0x0A,0x86,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Z_AXIS                          0x0A,0x87,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY                             0x0A,0x88,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW                         0x0A,0xE0,0x08
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM                      0x0A,0xE1,0x08
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH                        0x0A,0xE2,0x08
+
+//data type mechanical
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_MECHANICAL                                                0x0A,0x90,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_BOOLEAN_SWITCH_STATE                           0x0A,0x91,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_BOOLEAN_SWITCH_ARRAY_STATES                    0x0A,0x92,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_MULTIVALUE_SWITCH_VALUE                        0x0A,0x93,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_FORCE                                          0x0A,0x94,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_ABSOLUTE_PRESSURE                              0x0A,0x95,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_GAUGE_PRESSURE                                 0x0A,0x96,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_STRAIN                                         0x0A,0x97,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_WEIGHT                                         0x0A,0x98,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_MECHANICAL                                            0x0A,0xA0,0x04
+#define HID_USAGE_SENSOR_PROPERTY_MECHANICAL_VIBRATION_STATE                            0x0A,0xA1,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_VIBRATION_SPEED_FORWARD                        0x0A,0xA2,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_VIBRATION_SPEED_BACKWARD                       0x0A,0xA3,0x04
+
+//data type biometric
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC                                                 0x0A,0xB0,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PRESENCE                                  0x0A,0xB1,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE                           0x0A,0xB2,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_OUT_OF_RANGE                    0x0A,0xB3,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_TOUCH_STATE                               0x0A,0xB4,0x04
+
+//data type light sensor
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_LIGHT                                                     0x0A,0xD0,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE                                         0x0A,0xD1,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_COLOR_TEMPERATURE                                   0x0A,0xD2,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY                                        0x0A,0xD3,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_X                                      0x0A,0xD4,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_Y                                      0x0A,0xD5,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CONSUMER_IR_SENTENCE_RECEIVE                        0x0A,0xD6,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_LIGHT                                                 0x0A,0xE0,0x04
+#define HID_USAGE_SENSOR_PROPERTY_LIGHT_CONSUMER_IR_SENTENCE_SEND                       0x0A,0xE1,0x04
+
+//data type scanner
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_SCANNER                                                   0x0A,0xF0,0x04
+#define HID_USAGE_SENSOR_DATA_SCANNER_RFID_TAG                                          0x0A,0xF1,0x04
+#define HID_USAGE_SENSOR_DATA_SCANNER_NFC_SENTENCE_RECEIVE                              0x0A,0xF2,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_SCANNER                                               0x0A,0xF8,0x04
+#define HID_USAGE_SENSOR_PROPERTY_SCANNER_NFC_SENTENCE_SEND                             0x0A,0xF9,0x04
+
+//data type electrical
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL                                                0x0A,0x00,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_CAPACITANCE                                    0x0A,0x01,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_CURRENT                                        0x0A,0x02,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_POWER                                          0x0A,0x03,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_INDUCTANCE                                     0x0A,0x04,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_RESISTANCE                                     0x0A,0x05,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_VOLTAGE                                        0x0A,0x06,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_FREQUENCY                                      0x0A,0x07,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_PERIOD                                         0x0A,0x08,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_PERCENT_OF_RANGE                               0x0A,0x09,0x05
+
+//data type time
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_TIME                                                      0x0A,0x20,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_YEAR                                                 0x0A,0x21,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_MONTH                                                0x0A,0x22,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_DAY                                                  0x0A,0x23,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_DAY_OF_WEEK                                          0x0A,0x24,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_HOUR                                                 0x0A,0x25,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_MINUTE                                               0x0A,0x26,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_SECOND                                               0x0A,0x27,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_MILLISECOND                                          0x0A,0x28,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_TIMESTAMP                                            0x0A,0x29,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_JULIAN_DAY_OF_YEAR                                   0x0A,0x2A,0x05
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_TIME                                                  0x0A,0x30,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_TIME_ZONE_OFFSET_FROM_UTC                        0x0A,0x31,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_TIME_ZONE_NAME                                   0x0A,0x32,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_DAYLIGHT_SAVINGS_TIME_OBSERVED                   0x0A,0x33,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_TIME_TRIM_ADJUSTMENT                             0x0A,0x34,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_ARM_ALARM                                        0x0A,0x35,0x05
+
+//data type custom
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_CUSTOM                                                    0x0A,0x40,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_USAGE                                              0x0A,0x41,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_BOOLEAN_ARRAY                                      0x0A,0x42,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE                                              0x0A,0x43,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1                                            0x0A,0x44,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2                                            0x0A,0x45,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3                                            0x0A,0x46,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_4                                            0x0A,0x47,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_5                                            0x0A,0x48,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_6                                            0x0A,0x49,0x05
+
+#if 1 //define vendor-specific (non-spec) custom datafields
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_7                                            0x0A,0x4A,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_8                                            0x0A,0x4B,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_9                                            0x0A,0x4C,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_10                                           0x0A,0x4D,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_11                                           0x0A,0x4E,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_12                                           0x0A,0x4F,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_13                                           0x0A,0x50,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_14                                           0x0A,0x51,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_15                                           0x0A,0x52,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_16                                           0x0A,0x53,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_17                                           0x0A,0x54,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_18                                           0x0A,0x55,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_19                                           0x0A,0x56,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_20                                           0x0A,0x57,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_21                                           0x0A,0x58,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_22                                           0x0A,0x59,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_23                                           0x0A,0x5A,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_24                                           0x0A,0x5B,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_25                                           0x0A,0x5C,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_26                                           0x0A,0x5D,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_27                                           0x0A,0x5E,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_28                                           0x0A,0x5F,0x05
+#endif
+
+//data type generic
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_GENERIC                                                   0x0A,0x60,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_GUID_OR_PROPERTYKEY                               0x0A,0x61,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_CATEGORY_GUID                                     0x0A,0x62,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_TYPE_GUID                                         0x0A,0x63,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_EVENT_PROPERTYKEY                                 0x0A,0x64,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_PROPERTY_PROPERTYKEY                              0x0A,0x65,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_DATAFIELD_PROPERTYKEY                             0x0A,0x66,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_EVENT                                             0x0A,0x67,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_PROPERTY                                          0x0A,0x68,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_DATAFIELD                                         0x0A,0x69,0x05
+#define HID_USAGE_SENSOR_DATA_ENUMERATOR_TABLE_ROW_INDEX                                0x0A,0x6A,0x05
+#define HID_USAGE_SENSOR_DATA_ENUMERATOR_TABLE_ROW_COUNT                                0x0A,0x6B,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_GUID_OR_PROPERTYKEY_KIND                          0x0A,0x6C,0x05 // NAry
+//begin GorPK kind selectors
+#define HID_USAGE_SENSOR_GORPK_KIND_CATEGORY                                            0x0A,0xD0,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_TYPE                                                0x0A,0xD1,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_EVENT                                               0x0A,0xD2,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_PROPERTY                                            0x0A,0xD3,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_DATAFIELD                                           0x0A,0xD4,0x08 // Sel
+//end GorPK kind selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_GUID                                              0x0A,0x6D,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_PROPERTYKEY                                       0x0A,0x6E,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_TOP_LEVEL_COLLECTION_ID                           0x0A,0x6F,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_ID                                         0x0A,0x70,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_ITEM_POSITION_INDEX                        0x0A,0x71,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_FIRMWARE_VARTYPE                                  0x0A,0x72,0x05 // NAry
+//begin firmware vartype selectors
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_NULL                                       0x0A,0x00,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_BOOL                                       0x0A,0x01,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI1                                        0x0A,0x02,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I1                                         0x0A,0x03,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI2                                        0x0A,0x04,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I2                                         0x0A,0x05,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI4                                        0x0A,0x06,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I4                                         0x0A,0x07,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI8                                        0x0A,0x08,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I8                                         0x0A,0x09,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_R4                                         0x0A,0x0A,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_R8                                         0x0A,0x0B,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_WSTR                                       0x0A,0x0C,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_STR                                        0x0A,0x0D,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_CLSID                                      0x0A,0x0E,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_VECTOR_VT_UI1                              0x0A,0x0F,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E0                                      0x0A,0x10,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E1                                      0x0A,0x11,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E2                                      0x0A,0x12,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E3                                      0x0A,0x13,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E4                                      0x0A,0x14,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E5                                      0x0A,0x15,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E6                                      0x0A,0x16,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E7                                      0x0A,0x17,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E8                                      0x0A,0x18,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E9                                      0x0A,0x19,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EA                                      0x0A,0x1A,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EB                                      0x0A,0x1B,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EC                                      0x0A,0x1C,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16ED                                      0x0A,0x1D,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EE                                      0x0A,0x1E,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EF                                      0x0A,0x1F,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E0                                      0x0A,0x20,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E1                                      0x0A,0x21,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E2                                      0x0A,0x22,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E3                                      0x0A,0x23,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E4                                      0x0A,0x24,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E5                                      0x0A,0x25,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E6                                      0x0A,0x26,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E7                                      0x0A,0x27,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E8                                      0x0A,0x28,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E9                                      0x0A,0x29,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EA                                      0x0A,0x2A,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EB                                      0x0A,0x2B,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EC                                      0x0A,0x2C,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32ED                                      0x0A,0x2D,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EE                                      0x0A,0x2E,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EF                                      0x0A,0x2F,0x09 // Sel
+//end firmware vartype selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_UNIT_OF_MEASURE                                   0x0A,0x73,0x05 // NAry
+//begin unit of measure selectors
+#define HID_USAGE_SENSOR_GENERIC_UNIT_NOT_SPECIFIED                                     0x0A,0x40,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_LUX                                               0x0A,0x41,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_KELVIN                                    0x0A,0x42,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_CELSIUS                                   0x0A,0x43,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_PASCAL                                            0x0A,0x44,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_NEWTON                                            0x0A,0x45,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_METERS_PER_SECOND                                 0x0A,0x46,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_KILOGRAM                                          0x0A,0x47,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_METER                                             0x0A,0x48,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_METERS_PER_SEC_SQRD                               0x0A,0x49,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_FARAD                                             0x0A,0x4A,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_AMPERE                                            0x0A,0x4B,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_WATT                                              0x0A,0x4C,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_HENRY                                             0x0A,0x4D,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_OHM                                               0x0A,0x4E,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_VOLT                                              0x0A,0x4F,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_HERTZ                                             0x0A,0x50,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_BAR                                               0x0A,0x51,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_ANTI_CLOCKWISE                            0x0A,0x52,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_CLOCKWISE                                 0x0A,0x53,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES                                           0x0A,0x54,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_PER_SECOND                                0x0A,0x55,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_PER_SEC_SQRD                              0x0A,0x56,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_KNOT                                              0x0A,0x57,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_PERCENT                                           0x0A,0x58,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_SECOND                                            0x0A,0x59,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_MILLISECOND                                       0x0A,0x5A,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_G                                                 0x0A,0x5B,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_BYTES                                             0x0A,0x5C,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_MILLIGAUSS                                        0x0A,0x5D,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_BITS                                              0x0A,0x5E,0x09 // Sel
+//end unit of measure selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_UNIT_EXPONENT                                     0x0A,0x74,0x05 // NAry
+//begin unit exponent selectors
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_0                                             0x0A,0x70,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_1                                             0x0A,0x71,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_2                                             0x0A,0x72,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_3                                             0x0A,0x73,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_4                                             0x0A,0x74,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_5                                             0x0A,0x75,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_6                                             0x0A,0x76,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_7                                             0x0A,0x77,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_8                                             0x0A,0x78,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_9                                             0x0A,0x79,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_A                                             0x0A,0x7A,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_B                                             0x0A,0x7B,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_C                                             0x0A,0x7C,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_D                                             0x0A,0x7D,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_E                                             0x0A,0x7E,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_F                                             0x0A,0x7F,0x09 // Sel
+//end unit exponent selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_SIZE                                       0x0A,0x75,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_COUNT                                      0x0A,0x76,0x05
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_GENERIC                                               0x0A,0x80,0x05
+#define HID_USAGE_SENSOR_PROPERTY_ENUMERATOR_TABLE_ROW_INDEX                            0x0A,0x81,0x05
+#define HID_USAGE_SENSOR_PROPERTY_ENUMERATOR_TABLE_ROW_COUNT                            0x0A,0x82,0x05
+
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Other HID definitions
+//
+////////////////////////////////////////////////////////////////////////////////////
+
+//NOTE: These definitions are designed to permit compiling the HID report descriptors
+// with somewhat self-explanatory information to help readability and reduce errors
+
+//input,output,feature flags
+#define Data_Arr_Abs                            0x00
+#define Const_Arr_Abs                           0x01
+#define Data_Var_Abs                            0x02
+#define Const_Var_Abs                           0x03
+#define Data_Var_Rel                            0x06
+//collection flags
+#define Physical                                0x00
+#define Application                             0x01
+#define Logical                                 0x02
+#define NamedArray                              0x04
+#define UsageSwitch                             0x05
+//other
+#define Undefined                               0x00
+
+#define HID_USAGE_PAGE(a)                       0x05,a
+#define HID_USAGE(a)                            0x09,a
+#define HID_USAGE16(a,b)                        0x0A,a,b
+#define HID_USAGE_SENSOR_DATA(a,b)              a|b     //This or-s the mod into usage
+#define HID_COLLECTION(a)                       0xA1,a
+#define HID_REPORT_ID(a)                        0x85,a
+#define HID_REPORT_SIZE(a)                      0x75,a
+#define HID_REPORT_COUNT(a)                     0x95,a
+#define HID_USAGE_MIN_8(a)                      0x19,a
+#define HID_USAGE_MIN_16(a,b)                   0x1A,a,b
+#define HID_USAGE_MAX_8(a)                      0x29,a
+#define HID_USAGE_MAX_16(a,b)                   0x2A,a,b
+#define HID_LOGICAL_MIN_8(a)                    0x15,a
+#define HID_LOGICAL_MIN_16(a,b)                 0x16,a,b
+#define HID_LOGICAL_MIN_32(a,b,c,d)             0x17,a,b,c,d
+#define HID_LOGICAL_MAX_8(a)                    0x25,a
+#define HID_LOGICAL_MAX_16(a,b)                 0x26,a,b
+#define HID_LOGICAL_MAX_32(a,b,c,d)             0x27,a,b,c,d
+#define HID_UNIT_EXPONENT(a)                    0x55,a
+#define HID_INPUT(a)                            0x81,a
+#define HID_OUTPUT(a)                           0x91,a
+#define HID_FEATURE(a)                          0xB1,a
+#define HID_END_COLLECTION                      0xC0
+
+#endif // HIDUTIL_TEST_HIDSENSORSPEC_H
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TriStateTest.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/TriStateTest.cpp
new file mode 100644
index 0000000..9dcdf0b
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TriStateTest.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "TriState.h"
+#include <gtest/gtest.h>
+
+#include <cassert>
+#include <cstdint>
+#include <cstdio>
+#include <iostream>
+
+using HidUtil::TriState;
+typedef TriState<uint32_t> tri_uint32_t;
+typedef TriState<int32_t> tri_int32_t;
+typedef TriState<int16_t> tri_int16_t;
+
+TEST(TriStateTest, Constructor) {
+    tri_uint32_t a;
+    EXPECT_FALSE(a.isSet());
+
+    a += 1;
+    EXPECT_FALSE(a.isSet());
+
+    a -= 1;
+    EXPECT_FALSE(a.isSet());
+
+    a *= 1;
+    EXPECT_FALSE(a.isSet());
+
+    a /= 1;
+    EXPECT_FALSE(a.isSet());
+
+    tri_uint32_t b;
+    b = a;
+    EXPECT_FALSE(b.isSet());
+
+    a = 1;
+    EXPECT_TRUE(a.isSet());
+
+    b = a;
+    EXPECT_TRUE(b.isSet());
+
+    a.clear();
+    EXPECT_FALSE(a.isSet());
+    EXPECT_TRUE(b.isSet());
+
+    tri_uint32_t c(b);
+    EXPECT_TRUE(c.isSet());
+
+    c.clear();
+    EXPECT_FALSE(c.isSet());
+
+    tri_uint32_t d(a);
+    EXPECT_FALSE(c.isSet());
+}
+
+TEST(TriStateTest, IncAndDecOperation) {
+    tri_int32_t a(1);
+
+    EXPECT_EQ(2, (++a).get(0));
+    EXPECT_EQ(2, (a++).get(0));
+    EXPECT_EQ(3, a.get(0));
+
+    EXPECT_EQ(2, (--a).get(0));
+    EXPECT_EQ(2, (a--).get(0));
+    EXPECT_EQ(1, a.get(0));
+
+    tri_uint32_t b;
+    EXPECT_EQ(static_cast<uint32_t>(100), (++b).get(100));
+    EXPECT_EQ(static_cast<uint32_t>(101), (b++).get(101));
+    EXPECT_EQ(static_cast<uint32_t>(102), b.get(102));
+    EXPECT_FALSE(b.isSet());
+
+    EXPECT_EQ(static_cast<uint32_t>(103), (--b).get(103));
+    EXPECT_EQ(static_cast<uint32_t>(104), (b--).get(104));
+    EXPECT_EQ(static_cast<uint32_t>(105), b.get(105));
+    EXPECT_FALSE(b.isSet());
+}
+
+TEST(TriStateTest, Comparison) {
+    tri_int32_t a(1);
+    tri_int32_t b(1);
+    tri_int32_t c(2);
+    tri_int32_t d;
+
+    EXPECT_EQ(a, b);
+    EXPECT_FALSE((a != b));
+    EXPECT_TRUE(!(a != b));
+    EXPECT_NE(-1, a);
+
+    EXPECT_LT(a, c);
+    EXPECT_LT(a, 3);
+
+    EXPECT_GT(c, b);
+    EXPECT_GT(c, 0);
+
+    EXPECT_LE(a, 1);
+    EXPECT_LE(a, c);
+    EXPECT_LE(a, 3);
+    EXPECT_LE(a, b);
+
+    EXPECT_GE(c, b);
+    EXPECT_GE(b, a);
+    EXPECT_GE(c, 0);
+    EXPECT_GE(c, 2);
+
+    EXPECT_FALSE((a == d).isSet());
+    EXPECT_FALSE((a >= d).isSet());
+    EXPECT_FALSE((a <= d).isSet());
+    EXPECT_FALSE((a != d).isSet());
+    EXPECT_FALSE((a > d).isSet());
+    EXPECT_FALSE((a < d).isSet());
+
+    //EXPECT_EQ(a, d); // will cause runtime failure
+    // due to converting a not-set TriState<bool> to bool
+}
+
+TEST(TriStateTest, CompoundAssign) {
+    tri_uint32_t x;
+
+    x += 10;
+    EXPECT_FALSE(x.isSet());
+    x -= 10;
+    EXPECT_FALSE(x.isSet());
+    x *= 10;
+    EXPECT_FALSE(x.isSet());
+    x /= 10;
+    EXPECT_FALSE(x.isSet());
+    x &= 10;
+    EXPECT_FALSE(x.isSet());
+    x |= 10;
+    EXPECT_FALSE(x.isSet());
+    x %= 10;
+    EXPECT_FALSE(x.isSet());
+    x <<= 10;
+    EXPECT_FALSE(x.isSet());
+    x >>= 10;
+    EXPECT_FALSE(x.isSet());
+
+    tri_int32_t y, z, w;
+#define TEST_COMPOUND_ASSIGN(a, op, op_c, b) \
+    y = z = a; \
+    w = b; \
+    y op_c b; \
+    EXPECT_TRUE(y.isSet()); \
+    EXPECT_EQ(y, (a op b)); \
+    EXPECT_EQ(y, (z op b)); \
+    EXPECT_EQ(y, (a op w));
+
+    TEST_COMPOUND_ASSIGN(123, +, +=, 456);
+    TEST_COMPOUND_ASSIGN(123, -, -=, 456);
+    TEST_COMPOUND_ASSIGN(123, *, *=, 456);
+    TEST_COMPOUND_ASSIGN(123, /, /=, 456);
+    TEST_COMPOUND_ASSIGN(123, |, |=, 456);
+    TEST_COMPOUND_ASSIGN(123, &, &=, 456);
+    TEST_COMPOUND_ASSIGN(123, ^, ^=, 456);
+    TEST_COMPOUND_ASSIGN(123, %, %=, 456);
+#undef TEST_COMPOUND_ASSIGN
+    y = z = 123;
+    w = 10;
+    y <<= 10;
+    EXPECT_TRUE(y.isSet());
+    EXPECT_EQ(123 << 10, y);
+
+    y = z = 12345;
+    w = 10;
+    y >>= 10;
+    EXPECT_TRUE(y.isSet());
+    EXPECT_EQ(12345 >> 10, y);
+}
+
+TEST(TriStateTest, UnaryOperation) {
+    tri_int16_t p;
+    EXPECT_FALSE((!p).isSet());
+    EXPECT_FALSE((-p).isSet());
+    EXPECT_FALSE((~p).isSet());
+
+    tri_int16_t q(1234);
+    EXPECT_TRUE((!q).isSet());
+    EXPECT_EQ(!static_cast<int16_t>(1234), (!q));
+
+    tri_int16_t r(1234);
+    EXPECT_TRUE((-r).isSet());
+    EXPECT_EQ(-1234, (-r));
+
+    tri_int16_t s(1234);
+    EXPECT_TRUE((~s).isSet());
+    EXPECT_EQ(~static_cast<int16_t>(1234), ~s);
+}
+
diff --git a/modules/sensors/dynamic_sensor/RingBuffer.cpp b/modules/sensors/dynamic_sensor/RingBuffer.cpp
new file mode 100644
index 0000000..5857a7c
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/RingBuffer.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RingBuffer.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+RingBuffer::RingBuffer(size_t size)
+    : mSize(size),
+      mData((sensors_event_t *)malloc(sizeof(sensors_event_t) * mSize)),
+      mReadPos(0),
+      mWritePos(0) {
+}
+
+RingBuffer::~RingBuffer() {
+    free(mData);
+    mData = NULL;
+}
+
+ssize_t RingBuffer::write(const sensors_event_t *ev, size_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    size_t numAvailableToRead = mWritePos - mReadPos;
+    size_t numAvailableToWrite = mSize - numAvailableToRead;
+
+    if (size > numAvailableToWrite) {
+        size = numAvailableToWrite;
+    }
+
+    size_t writePos = (mWritePos % mSize);
+    size_t copy = mSize - writePos;
+
+    if (copy > size) {
+        copy = size;
+    }
+
+    memcpy(&mData[writePos], ev, copy * sizeof(sensors_event_t));
+
+    if (size > copy) {
+        memcpy(mData, &ev[copy], (size - copy) * sizeof(sensors_event_t));
+    }
+
+    mWritePos += size;
+
+    if (numAvailableToRead == 0 && size > 0) {
+        mNotEmptyCondition.broadcast();
+    }
+
+    return size;
+}
+
+ssize_t RingBuffer::read(sensors_event_t *ev, size_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    size_t numAvailableToRead;
+    for (;;) {
+        numAvailableToRead = mWritePos - mReadPos;
+        if (numAvailableToRead > 0) {
+            break;
+        }
+
+        mNotEmptyCondition.wait(mLock);
+    }
+
+    if (size > numAvailableToRead) {
+        size = numAvailableToRead;
+    }
+
+    size_t readPos = (mReadPos % mSize);
+    size_t copy = mSize - readPos;
+
+    if (copy > size) {
+        copy = size;
+    }
+
+    memcpy(ev, &mData[readPos], copy * sizeof(sensors_event_t));
+
+    if (size > copy) {
+        memcpy(&ev[copy], mData, (size - copy) * sizeof(sensors_event_t));
+    }
+
+    mReadPos += size;
+
+    return size;
+}
+
+}  // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/RingBuffer.h b/modules/sensors/dynamic_sensor/RingBuffer.h
new file mode 100644
index 0000000..aa6b8c9
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/RingBuffer.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RING_BUFFER_H_
+
+#define RING_BUFFER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+
+#include <hardware/sensors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class RingBuffer {
+public:
+    explicit RingBuffer(size_t size);
+    ~RingBuffer();
+
+    ssize_t write(const sensors_event_t *ev, size_t size);
+    ssize_t read(sensors_event_t *ev, size_t size);
+
+private:
+    Mutex mLock;
+    Condition mNotEmptyCondition;
+
+    size_t mSize;
+    sensors_event_t *mData;
+    size_t mReadPos, mWritePos;
+
+    DISALLOW_EVIL_CONSTRUCTORS(RingBuffer);
+};
+
+}  // namespace android
+
+#endif  // RING_BUFFER_H_
diff --git a/modules/sensors/dynamic_sensor/SensorEventCallback.h b/modules/sensors/dynamic_sensor/SensorEventCallback.h
new file mode 100644
index 0000000..2f79529
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/SensorEventCallback.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
+#define ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
+
+#include "Utils.h"
+#include <hardware/sensors.h>
+
+namespace android {
+namespace SensorHalExt {
+class BaseSensorObject;
+
+// if timestamp in sensors_event_t has this value, it will be filled at dispatcher.
+constexpr int64_t TIMESTAMP_AUTO_FILL = -1;
+
+class SensorEventCallback {
+public:
+    virtual int submitEvent(SP(BaseSensorObject) sensor, const sensors_event_t &e) = 0;
+    virtual ~SensorEventCallback() = default;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
diff --git a/modules/sensors/dynamic_sensor/Utils.h b/modules/sensors/dynamic_sensor/Utils.h
new file mode 100644
index 0000000..c96c147
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/Utils.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SENSORHAL_EXT_UTILS_H
+#define ANDROID_SENSORHAL_EXT_UTILS_H
+
+// Host build does not have RefBase
+#ifdef __ANDROID__
+#include <utils/RefBase.h>
+#define REF_BASE(a) ::android::RefBase
+#define SP(a) sp<a>
+#define WP(a) wp<a>
+#define SP_THIS this
+#define PROMOTE(a) (a).promote()
+#else
+#include <memory>
+#define REF_BASE(a) std::enable_shared_from_this<a>
+#define SP(a) std::shared_ptr<a>
+#define WP(a) std::weak_ptr<a>
+#define SP_THIS shared_from_this()
+#define PROMOTE(a) (a).lock()
+#endif
+
+#endif // ANDROID_SENSORHAL_EXT_UTILS_H
diff --git a/modules/sensors/dynamic_sensor/sensors.cpp b/modules/sensors/dynamic_sensor/sensors.cpp
new file mode 100644
index 0000000..7c203b2
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/sensors.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "DynamicSensorManager.h"
+#include "sensors.h"
+
+#include <cutils/properties.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <string.h>
+using namespace android;
+
+////////////////////////////////////////////////////////////////////////////////
+
+SensorContext::SensorContext(const struct hw_module_t *module) {
+    memset(&device, 0, sizeof(device));
+
+    device.common.tag = HARDWARE_DEVICE_TAG;
+    device.common.version = SENSORS_DEVICE_API_VERSION_1_3;
+    device.common.module = const_cast<hw_module_t *>(module);
+    device.common.close = CloseWrapper;
+    device.activate = ActivateWrapper;
+    device.setDelay = SetDelayWrapper;
+    device.poll = PollWrapper;
+    device.batch = BatchWrapper;
+    device.flush = FlushWrapper;
+
+    // initialize dynamic sensor manager
+    int32_t base = property_get_int32("sensor.dynamic_sensor_hal.handle_base", kDynamicHandleBase);
+    int32_t count =
+            property_get_int32("sensor.dynamic_sensor_hal.handle_count", kMaxDynamicHandleCount);
+    mDynamicSensorManager.reset(DynamicSensorManager::createInstance(base, count, nullptr));
+}
+
+int SensorContext::close() {
+    delete this;
+    return 0;
+}
+
+int SensorContext::activate(int handle, int enabled) {
+    return mDynamicSensorManager->activate(handle, enabled);
+}
+
+int SensorContext::setDelay(int handle, int64_t delayNs) {
+    return mDynamicSensorManager->setDelay(handle, delayNs);
+}
+
+int SensorContext::poll(sensors_event_t *data, int count) {
+    return mDynamicSensorManager->poll(data, count);
+}
+
+int SensorContext::batch(
+        int handle,
+        int64_t sampling_period_ns,
+        int64_t max_report_latency_ns) {
+    return mDynamicSensorManager->batch(handle, sampling_period_ns, max_report_latency_ns);
+}
+
+int SensorContext::flush(int handle) {
+    return mDynamicSensorManager->flush(handle);
+}
+
+// static
+int SensorContext::CloseWrapper(struct hw_device_t *dev) {
+    return reinterpret_cast<SensorContext *>(dev)->close();
+}
+
+// static
+int SensorContext::ActivateWrapper(
+        struct sensors_poll_device_t *dev, int handle, int enabled) {
+    return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
+}
+
+// static
+int SensorContext::SetDelayWrapper(
+        struct sensors_poll_device_t *dev, int handle, int64_t delayNs) {
+    return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, delayNs);
+}
+
+// static
+int SensorContext::PollWrapper(
+        struct sensors_poll_device_t *dev, sensors_event_t *data, int count) {
+    return reinterpret_cast<SensorContext *>(dev)->poll(data, count);
+}
+
+// static
+int SensorContext::BatchWrapper(
+        struct sensors_poll_device_1 *dev,
+        int handle,
+        int flags,
+        int64_t sampling_period_ns,
+        int64_t max_report_latency_ns) {
+    (void) flags;
+    return reinterpret_cast<SensorContext *>(dev)->batch(
+            handle, sampling_period_ns, max_report_latency_ns);
+}
+
+// static
+int SensorContext::FlushWrapper(struct sensors_poll_device_1 *dev, int handle) {
+    return reinterpret_cast<SensorContext *>(dev)->flush(handle);
+}
+
+size_t SensorContext::getSensorList(sensor_t const **list) {
+    *list = &(mDynamicSensorManager->getDynamicMetaSensor());
+    return 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static sensor_t const *sensor_list;
+
+static int open_sensors(
+        const struct hw_module_t *module,
+        const char *,
+        struct hw_device_t **dev) {
+    SensorContext *ctx = new SensorContext(module);
+    ctx->getSensorList(&sensor_list);
+    *dev = &ctx->device.common;
+    return 0;
+}
+
+static struct hw_module_methods_t sensors_module_methods = {
+    .open = open_sensors
+};
+
+static int get_sensors_list(
+        struct sensors_module_t *,
+        struct sensor_t const **list) {
+    *list = sensor_list;
+    return 1;
+}
+
+static int set_operation_mode(unsigned int mode) {
+    return (mode) ? -EINVAL : 0;
+}
+
+struct sensors_module_t HAL_MODULE_INFO_SYM = {
+    .common = {
+            .tag = HARDWARE_MODULE_TAG,
+            .version_major = 1,
+            .version_minor = 0,
+            .id = SENSORS_HARDWARE_MODULE_ID,
+            .name = "Google Dynamic Sensor Manager",
+            .author = "Google",
+            .methods = &sensors_module_methods,
+            .dso  = NULL,
+            .reserved = {0},
+    },
+    .get_sensors_list = get_sensors_list,
+    .set_operation_mode = set_operation_mode,
+};
diff --git a/modules/sensors/dynamic_sensor/sensors.h b/modules/sensors/dynamic_sensor/sensors.h
new file mode 100644
index 0000000..2fd8708
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/sensors.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SENSORS_H_
+#define SENSORS_H_
+
+#include <hardware/hardware.h>
+#include <hardware/sensors.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+
+#include <memory>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+    namespace SensorHalExt {
+        class DynamicSensorManager;
+    } // namespace BaseSensorObject
+} // namespace android
+
+using android::SensorHalExt::DynamicSensorManager;
+
+class SensorContext {
+public:
+    struct sensors_poll_device_1 device;
+
+    explicit SensorContext(const struct hw_module_t *module);
+
+    size_t getSensorList(sensor_t const **list);
+
+private:
+
+    int close();
+    int activate(int handle, int enabled);
+    int setDelay(int handle, int64_t delayNs);
+    int poll(sensors_event_t *data, int count);
+
+    int batch(int handle, int64_t sampling_period_ns,
+              int64_t max_report_latency_ns);
+
+    int flush(int handle);
+
+    // static wrappers
+    static int CloseWrapper(struct hw_device_t *dev);
+
+    static int ActivateWrapper(
+            struct sensors_poll_device_t *dev, int handle, int enabled);
+
+    static int SetDelayWrapper(
+            struct sensors_poll_device_t *dev, int handle, int64_t delayNs);
+
+    static int PollWrapper(
+            struct sensors_poll_device_t *dev, sensors_event_t *data, int count);
+
+    static int BatchWrapper(
+            struct sensors_poll_device_1 *dev,
+            int handle,
+            int flags,
+            int64_t sampling_period_ns,
+            int64_t max_report_latency_ns);
+
+    static int FlushWrapper(struct sensors_poll_device_1 *dev, int handle);
+
+    static constexpr int32_t kDynamicHandleBase = 0x10000;
+    static constexpr int32_t kDynamicHandleEnd = 0x1000000;
+    static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - kDynamicHandleBase;
+
+    std::unique_ptr<DynamicSensorManager> mDynamicSensorManager;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SensorContext);
+};
+
+#endif  // SENSORS_H_
diff --git a/modules/sensors/dynamic_sensor/test/HidRawDeviceTest.cpp b/modules/sensors/dynamic_sensor/test/HidRawDeviceTest.cpp
new file mode 100644
index 0000000..2a68e39
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/test/HidRawDeviceTest.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "HidRawDeviceTest"
+
+#include "HidRawDevice.h"
+#include "HidRawSensor.h"
+#include "HidSensorDef.h"
+#include "SensorEventCallback.h"
+#include "Utils.h"
+#include "HidLog.h"
+#include "StreamIoUtil.h"
+
+namespace android {
+namespace SensorHalExt {
+
+/*
+ * Host test that verifies HidRawDevice and HidRawSensor works correctly.
+ */
+class HidRawDeviceTest {
+public:
+    static void test(const char *devicePath) {
+        using namespace Hid::Sensor::SensorTypeUsage;
+        using HidUtil::hexdumpToStream;
+
+        std::unordered_set<unsigned int> interestedUsage{
+                ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM};
+
+        SP(HidRawDevice) device =
+                std::make_shared<HidRawDevice>(std::string(devicePath), interestedUsage);
+        const HidDevice::HidDeviceInfo &info = device->getDeviceInfo();
+
+        LOG_V << "Sizeof descriptor: " << info.descriptor.size() << LOG_ENDL;
+        LOG_V << "Descriptor: " << LOG_ENDL;
+        hexdumpToStream(LOG_V, info.descriptor.begin(), info.descriptor.end());
+
+        if (!device->isValid()) {
+            LOG_E << "invalid device" << LOG_ENDL;
+            return;
+        }
+
+        LOG_V << "Digest: " << LOG_ENDL;
+        LOG_V << device->mDigestVector;
+
+        std::vector<uint8_t> buffer;
+        // Dump first few feature ID to help debugging.
+        // If device does not implement all these features, it will show error messages.
+        for (int featureId = 0; featureId <= 5; ++featureId) {
+            if (!device->getFeature(featureId, &buffer)) {
+                LOG_E << "cannot get feature " << featureId << LOG_ENDL;
+            } else {
+                LOG_V << "Dump of feature " << featureId << LOG_ENDL;
+                hexdumpToStream(LOG_V, buffer.begin(), buffer.end());
+            }
+        }
+        //
+        // use HidRawSensor to operate the device, pick first digest
+        //
+        auto &reportDigest = device->mDigestVector[0];
+        SP(HidRawSensor) sensor = std::make_shared<HidRawSensor>(
+                device, reportDigest.fullUsage, reportDigest.packets);
+
+        if (!sensor->isValid()) {
+            LOG_E << "Sensor is not valid " << LOG_ENDL;
+            return;
+        }
+
+        const sensor_t *s = sensor->getSensor();
+        LOG_V << "Sensor name: " << s->name << ", vendor: " << s->vendor << LOG_ENDL;
+        LOG_V << sensor->dump() << LOG_ENDL;
+
+        class Callback : public SensorEventCallback {
+            virtual int submitEvent(SP(BaseSensorObject) /*sensor*/, const sensors_event_t &e) {
+                LOG_V << "sensor: " << e.sensor << ", type: " << e.type << ", ts: " << e.timestamp
+                      << ", values (" << e.data[0] << ", " << e.data[1] << ", " << e.data[2] << ")"
+                      << LOG_ENDL;
+                return 1;
+            }
+        };
+        Callback callback;
+        sensor->setEventCallback(&callback);
+
+        // Request sensor samples at to 10Hz (100ms)
+        sensor->batch(100LL*1000*1000 /*ns*/, 0);
+        sensor->enable(true);
+
+        // get a couple of events
+        for (size_t i = 0; i < 100; ++i) {
+            uint8_t id;
+            if (!device->receiveReport(&id, &buffer)) {
+                LOG_E << "Receive report error" << LOG_ENDL;
+                continue;
+            }
+            sensor->handleInput(id, buffer);
+        }
+
+        // clean up
+        sensor->enable(false);
+
+        LOG_V << "Done!" << LOG_ENDL;
+    }
+};
+} //namespace SensorHalExt
+} //namespace android
+
+int main(int argc, char* argv[]) {
+    if (argc != 2) {
+        LOG_E << "Usage: " << argv[0] << " hidraw-dev-path" << LOG_ENDL;
+        return -1;
+    }
+    android::SensorHalExt::HidRawDeviceTest::test(argv[1]);
+    return 0;
+}
diff --git a/modules/sensors/dynamic_sensor/test/HidRawSensorTest.cpp b/modules/sensors/dynamic_sensor/test/HidRawSensorTest.cpp
new file mode 100644
index 0000000..66a747a
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/test/HidRawSensorTest.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "HidRawSensorTest"
+
+#include "HidDevice.h"
+#include "HidLog.h"
+#include "HidLog.h"
+#include "HidParser.h"
+#include "HidRawSensor.h"
+#include "HidSensorDef.h"
+#include "StreamIoUtil.h"
+#include "TestHidDescriptor.h"
+#include "Utils.h"
+
+#include <deque>
+#include <unordered_map>
+
+namespace android {
+namespace SensorHalExt {
+
+class HidRawDummyDevice : public HidDevice {
+public:
+    struct DataPair {
+        uint8_t id;
+        std::vector<uint8_t> data;
+    };
+
+    HidRawDummyDevice() {
+        // dummy values
+        mInfo = {
+          .name = "Test sensor name",
+          .physicalPath = "/physical/path",
+          .busType = "USB",
+          .vendorId = 0x1234,
+          .productId = 0x5678,
+          .descriptor = {0}
+      };
+    }
+
+    virtual const HidDeviceInfo& getDeviceInfo() {
+        return mInfo;
+    }
+
+    // get feature from device
+    virtual bool getFeature(uint8_t id, std::vector<uint8_t> *out) {
+        auto i = mFeature.find(id);
+        if (i == mFeature.end()) {
+            return false;
+        }
+        *out = i->second;
+        return true;
+    }
+
+    // write feature to device
+    virtual bool setFeature(uint8_t id, const std::vector<uint8_t> &in) {
+        auto i = mFeature.find(id);
+        if (i == mFeature.end() || in.size() != i->second.size()) {
+            return false;
+        }
+        i->second = in;
+        return true;
+    }
+
+    // send report to default output endpoint
+    virtual bool sendReport(uint8_t id, std::vector<uint8_t> &data) {
+        DataPair pair = {
+            .id = id,
+            .data = data
+        };
+        mOutput.push_back(pair);
+        return true;
+    }
+
+    // receive from default input endpoint
+    virtual bool receiveReport(uint8_t * /*id*/, std::vector<uint8_t> * /*data*/) {
+        // not necessary, as input report can be directly feed to HidRawSensor for testing purpose
+        return false;
+    }
+
+    bool dequeuOutputReport(DataPair *pair) {
+        if (!mOutput.empty()) {
+            return false;
+        }
+        *pair = mOutput.front();
+        mOutput.pop_front();
+        return true;
+    }
+
+private:
+    HidDeviceInfo mInfo;
+    std::deque<DataPair> mOutput;
+    std::unordered_map<uint8_t, std::vector<uint8_t>> mFeature;
+};
+
+class HidRawSensorTest {
+public:
+    static bool test() {
+        bool ret = true;
+        using namespace Hid::Sensor::SensorTypeUsage;
+        std::unordered_set<unsigned int> interestedUsage{
+                ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM};
+        SP(HidDevice) device(new HidRawDummyDevice());
+
+        HidParser hidParser;
+        for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+            if (p->data == nullptr || p->len == 0) {
+                break;
+            }
+            const char *name = p->name != nullptr ? p->name : "unnamed";
+            if (!hidParser.parse(p->data, p->len)) {
+                LOG_E << name << " parsing error!" << LOG_ENDL;
+                ret = false;
+                continue;
+            }
+
+            hidParser.filterTree();
+            LOG_V << name << "  digest: " << LOG_ENDL;
+            auto digestVector = hidParser.generateDigest(interestedUsage);
+            LOG_V << digestVector;
+
+            if (digestVector.empty()) {
+                LOG_V << name << " does not contain interested usage" << LOG_ENDL;
+                continue;
+            }
+
+            LOG_V << name << "  sensor: " << LOG_ENDL;
+            for (const auto &digest : digestVector) {
+                LOG_I << "Sensor usage " << std::hex << digest.fullUsage << std::dec << LOG_ENDL;
+                auto *s = new HidRawSensor(device, digest.fullUsage, digest.packets);
+                if (s->mValid) {
+                    LOG_V << "Usage " << std::hex << digest.fullUsage << std::dec << LOG_ENDL;
+                    LOG_V << s->dump();
+                } else {
+                    LOG_V << "Sensor of usage " << std::hex << digest.fullUsage << std::dec
+                          << " not valid!" << LOG_ENDL;
+                }
+            }
+            LOG_V << LOG_ENDL;
+        }
+        return ret;
+    }
+};
+
+}// namespace SensorHalExt
+}// namespace android
+
+int main() {
+    return android::SensorHalExt::HidRawSensorTest::test() ? 0 : 1;
+}
diff --git a/modules/sensors/multihal.cpp b/modules/sensors/multihal.cpp
index f38d90d..2810118 100644
--- a/modules/sensors/multihal.cpp
+++ b/modules/sensors/multihal.cpp
@@ -14,33 +14,30 @@
  * limitations under the License.
  */
 
-#include <hardware/sensors.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <math.h>
-#include <poll.h>
-#include <pthread.h>
-#include <cutils/atomic.h>
+#include "SensorEventQueue.h"
+#include "multihal.h"
 
 #define LOG_NDEBUG 1
 #include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <hardware/sensors.h>
 
 #include <vector>
 #include <string>
 #include <fstream>
 #include <map>
-#include <string>
 
-#include <stdio.h>
+#include <dirent.h>
 #include <dlfcn.h>
-#include <SensorEventQueue.h>
-
+#include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
+#include <math.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdio.h>
 #include <stdlib.h>
 
-static const char* CONFIG_FILENAME = "/system/etc/sensors/hals.conf";
-static const int MAX_CONF_LINE_LENGTH = 1024;
 
 static pthread_mutex_t init_modules_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t init_sensors_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -258,9 +255,9 @@
     }
 }
 
-// Android L requires sensor HALs to be either 1_0 or 1_3 compliant
+// Android N and hire require sensor HALs to be at least 1_3 compliant
 #define HAL_VERSION_IS_COMPLIANT(version)  \
-    (version == SENSORS_DEVICE_API_VERSION_1_0 || version >= SENSORS_DEVICE_API_VERSION_1_3)
+    (version >= SENSORS_DEVICE_API_VERSION_1_3)
 
 // Returns true if HAL is compliant, false if HAL is not compliant or if handle is invalid
 static bool halIsCompliant(sensors_poll_context_t *ctx, int handle) {
@@ -504,13 +501,13 @@
  */
 static void get_so_paths(std::vector<std::string> *so_paths) {
     std::string line;
-    std::ifstream conf_file(CONFIG_FILENAME);
+    std::ifstream conf_file(MULTI_HAL_CONFIG_FILE_PATH);
 
     if(!conf_file) {
-        ALOGW("No multihal config file found at %s", CONFIG_FILENAME);
+        ALOGW("No multihal config file found at %s", MULTI_HAL_CONFIG_FILE_PATH);
         return;
     }
-    ALOGV("Multihal config file found at %s", CONFIG_FILENAME);
+    ALOGV("Multihal config file found at %s", MULTI_HAL_CONFIG_FILE_PATH);
     while (std::getline(conf_file, line)) {
         ALOGV("config file line: '%s'", line.c_str());
         so_paths->push_back(line);
@@ -660,6 +657,10 @@
     .get_sensors_list = module__get_sensors_list
 };
 
+struct sensors_module_t *get_multi_hal_module_info() {
+    return (&HAL_MODULE_INFO_SYM);
+}
+
 static int open_sensors(const struct hw_module_t* hw_module, const char* name,
         struct hw_device_t** hw_device_out) {
     ALOGV("open_sensors begin...");
diff --git a/modules/sensors/multihal.h b/modules/sensors/multihal.h
new file mode 100644
index 0000000..210c7cc
--- /dev/null
+++ b/modules/sensors/multihal.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HARDWARE_LIBHARDWARE_MODULES_SENSORS_MULTIHAL_H_
+#define HARDWARE_LIBHARDWARE_MODULES_SENSORS_MULTIHAL_H_
+
+#include <hardware/sensors.h>
+#include <hardware/hardware.h>
+
+static const char* MULTI_HAL_CONFIG_FILE_PATH = "/system/etc/sensors/hals.conf";
+
+struct sensors_module_t *get_multi_hal_module_info(void);
+
+#endif // HARDWARE_LIBHARDWARE_MODULES_SENSORS_MULTIHAL_H_
diff --git a/modules/sensors/tests/SensorEventQueue_test.cpp b/modules/sensors/tests/SensorEventQueue_test.cpp
index 3218bb9..d3d75ee 100644
--- a/modules/sensors/tests/SensorEventQueue_test.cpp
+++ b/modules/sensors/tests/SensorEventQueue_test.cpp
@@ -32,7 +32,7 @@
     return true;
 }
 
-bool checkInt(char* msg, int expected, int actual) {
+bool checkInt(const char* msg, int expected, int actual) {
     if (actual != expected) {
         printf("%s; expected %d; actual was %d\n", msg, expected, actual);
         return false;
@@ -187,7 +187,7 @@
 }
 
 
-int main(int argc, char **argv) {
+int main(int argc __attribute((unused)), char **argv __attribute((unused))) {
     if (testSimpleWriteSizeCounts() &&
             testWrappingWriteSizeCounts() &&
             testFullQueueIo()) {
diff --git a/modules/soundtrigger/Android.mk b/modules/soundtrigger/Android.mk
index bb58053..8250f9b 100644
--- a/modules/soundtrigger/Android.mk
+++ b/modules/soundtrigger/Android.mk
@@ -19,6 +19,7 @@
 
 LOCAL_MODULE := sound_trigger.stub.default
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SRC_FILES := sound_trigger_hw.c
 LOCAL_SHARED_LIBRARIES := liblog libcutils
 LOCAL_MODULE_TAGS := optional
diff --git a/modules/thermal/Android.mk b/modules/thermal/Android.mk
index 80ad78a..ff51145 100644
--- a/modules/thermal/Android.mk
+++ b/modules/thermal/Android.mk
@@ -18,6 +18,7 @@
 
 LOCAL_MODULE := thermal.default
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SRC_FILES := thermal.c
 LOCAL_SHARED_LIBRARIES := liblog libcutils
 LOCAL_MODULE_TAGS := optional
diff --git a/modules/thermal/thermal.c b/modules/thermal/thermal.c
index 6ba5845..7f4de3b 100644
--- a/modules/thermal/thermal.c
+++ b/modules/thermal/thermal.c
@@ -138,8 +138,9 @@
             fclose(file);
             fclose(cpu_file);
             return errno ? -errno : -EIO;
+        } else {
+            fclose(cpu_file);
         }
-        fclose(cpu_file);
 
         if (list != NULL) {
             list[size] = (cpu_usage_t) {
diff --git a/modules/tv_input/Android.bp b/modules/tv_input/Android.bp
new file mode 100644
index 0000000..509198d
--- /dev/null
+++ b/modules/tv_input/Android.bp
@@ -0,0 +1,24 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "tv_input.default",
+    relative_install_path: "hw",
+    proprietary: true,
+    shared_libs: [
+        "libcutils",
+        "liblog",
+    ],
+    srcs: ["tv_input.cpp"],
+}
diff --git a/modules/tv_input/Android.mk b/modules/tv_input/Android.mk
deleted file mode 100644
index e8aa7fc..0000000
--- a/modules/tv_input/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SHARED_LIBRARIES := libcutils liblog
-LOCAL_SRC_FILES := tv_input.cpp
-LOCAL_MODULE := tv_input.default
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/tv_input/tv_input.cpp b/modules/tv_input/tv_input.cpp
index 114e80e..ddace28 100644
--- a/modules/tv_input/tv_input.cpp
+++ b/modules/tv_input/tv_input.cpp
@@ -37,18 +37,18 @@
         const char* name, struct hw_device_t** device);
 
 static struct hw_module_methods_t tv_input_module_methods = {
-    open: tv_input_device_open
+    .open = tv_input_device_open
 };
 
 tv_input_module_t HAL_MODULE_INFO_SYM = {
-    common: {
-        tag: HARDWARE_MODULE_TAG,
-        version_major: 0,
-        version_minor: 1,
-        id: TV_INPUT_HARDWARE_MODULE_ID,
-        name: "Sample TV input module",
-        author: "The Android Open Source Project",
-        methods: &tv_input_module_methods,
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .version_major = 0,
+        .version_minor = 1,
+        .id = TV_INPUT_HARDWARE_MODULE_ID,
+        .name = "Sample TV input module",
+        .author = "The Android Open Source Project",
+        .methods = &tv_input_module_methods,
     }
 };
 
diff --git a/modules/usbaudio/Android.mk b/modules/usbaudio/Android.mk
index 9df1e79..b36bf9f 100644
--- a/modules/usbaudio/Android.mk
+++ b/modules/usbaudio/Android.mk
@@ -18,6 +18,7 @@
 
 LOCAL_MODULE := audio.usb.default
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SRC_FILES := \
 	audio_hal.c
 LOCAL_C_INCLUDES += \
diff --git a/modules/usbcamera/Camera.cpp b/modules/usbcamera/Camera.cpp
index cf62f7f..b396291 100644
--- a/modules/usbcamera/Camera.cpp
+++ b/modules/usbcamera/Camera.cpp
@@ -484,9 +484,9 @@
     // TODO: dump all settings
     dprintf(fd, "Most Recent Settings: (%p)\n", mSettings);
 
-    dprintf(fd, "Number of streams: %d\n", mStreams.size());
+    dprintf(fd, "Number of streams: %zu\n", mStreams.size());
     for (size_t i = 0; i < mStreams.size(); i++) {
-        dprintf(fd, "Stream %d/%d:\n", i, mStreams.size());
+        dprintf(fd, "Stream %zu/%zu:\n", i, mStreams.size());
         mStreams[i]->dump(fd);
     }
 }
diff --git a/modules/usbcamera/Camera.h b/modules/usbcamera/Camera.h
index 6419c7d..4051345 100644
--- a/modules/usbcamera/Camera.h
+++ b/modules/usbcamera/Camera.h
@@ -38,7 +38,7 @@
     public:
         // id is used to distinguish cameras. 0 <= id < NUM_CAMERAS.
         // module is a handle to the HAL module, used when the device is opened.
-        Camera(int id);
+        explicit Camera(int id);
         virtual ~Camera();
 
         // Common Camera Device Operations (see <hardware/camera_common.h>)
diff --git a/modules/usbcamera/CameraHAL.cpp b/modules/usbcamera/CameraHAL.cpp
index 652e937..c54283b 100644
--- a/modules/usbcamera/CameraHAL.cpp
+++ b/modules/usbcamera/CameraHAL.cpp
@@ -65,7 +65,7 @@
 
 int CameraHAL::getNumberOfCameras() {
     android::Mutex::Autolock al(mModuleLock);
-    ALOGV("%s: %d", __func__, mCameras.size());
+    ALOGV("%s: %zu", __func__, mCameras.size());
     return static_cast<int>(mCameras.size());
 }
 
@@ -126,29 +126,29 @@
 }
 
 static hw_module_methods_t gCameraModuleMethods = {
-    open : open_dev
+    .open = open_dev
 };
 
 camera_module_t HAL_MODULE_INFO_SYM __attribute__ ((visibility("default"))) = {
-    common : {
-        tag                : HARDWARE_MODULE_TAG,
-        module_api_version : CAMERA_MODULE_API_VERSION_2_4,
-        hal_api_version    : HARDWARE_HAL_API_VERSION,
-        id                 : CAMERA_HARDWARE_MODULE_ID,
-        name               : "Default USB Camera HAL",
-        author             : "The Android Open Source Project",
-        methods            : &gCameraModuleMethods,
-        dso                : NULL,
-        reserved           : {0},
+    .common = {
+        .tag                = HARDWARE_MODULE_TAG,
+        .module_api_version = CAMERA_MODULE_API_VERSION_2_4,
+        .hal_api_version    = HARDWARE_HAL_API_VERSION,
+        .id                 = CAMERA_HARDWARE_MODULE_ID,
+        .name               = "Default USB Camera HAL",
+        .author             = "The Android Open Source Project",
+        .methods            = &gCameraModuleMethods,
+        .dso                = NULL,
+        .reserved           = {0},
     },
-    get_number_of_cameras : get_number_of_cameras,
-    get_camera_info       : get_camera_info,
-    set_callbacks         : set_callbacks,
-    get_vendor_tag_ops    : NULL,
-    open_legacy           : NULL,
-    set_torch_mode        : NULL,
-    init                  : NULL,
-    reserved              : {0},
+    .get_number_of_cameras = get_number_of_cameras,
+    .get_camera_info       = get_camera_info,
+    .set_callbacks         = set_callbacks,
+    .get_vendor_tag_ops    = NULL,
+    .open_legacy           = NULL,
+    .set_torch_mode        = NULL,
+    .init                  = NULL,
+    .reserved              = {0},
 };
 } // extern "C"
 
diff --git a/modules/usbcamera/HotplugThread.cpp b/modules/usbcamera/HotplugThread.cpp
index 6c65086..02e7167 100644
--- a/modules/usbcamera/HotplugThread.cpp
+++ b/modules/usbcamera/HotplugThread.cpp
@@ -39,6 +39,7 @@
 }
 
 bool HotplugThread::threadLoop() {
+    (void)mModule;  // silence warning about unused member.
 
     /**
      * Check camera connection status change, if connected, do below:
diff --git a/modules/usbcamera/HotplugThread.h b/modules/usbcamera/HotplugThread.h
index a13adb7..625dcb4 100644
--- a/modules/usbcamera/HotplugThread.h
+++ b/modules/usbcamera/HotplugThread.h
@@ -36,7 +36,7 @@
 class HotplugThread : public android::Thread {
 
     public:
-        HotplugThread(CameraHAL *hal);
+        explicit HotplugThread(CameraHAL *hal);
         ~HotplugThread();
 
         // Override below two methods for proper cleanup.
diff --git a/modules/usbcamera/Stream.cpp b/modules/usbcamera/Stream.cpp
index f56866e..2b83421 100644
--- a/modules/usbcamera/Stream.cpp
+++ b/modules/usbcamera/Stream.cpp
@@ -170,10 +170,9 @@
     // ToDo: prettyprint usage mask flags
     dprintf(fd, "Gralloc Usage Mask: %#" PRIx32 "\n", mStream->usage);
     dprintf(fd, "Max Buffer Count: %" PRIu32 "\n", mStream->max_buffers);
-    dprintf(fd, "Number of Buffers in use by HAL: %" PRIu32 "\n", mBuffers.size());
+    dprintf(fd, "Number of Buffers in use by HAL: %zu\n", mBuffers.size());
     for (size_t i = 0; i < mBuffers.size(); i++) {
-        dprintf(fd, "Buffer %" PRIu32 "/%" PRIu32 ": %p\n", i, mBuffers.size(),
-                mBuffers[i]);
+        dprintf(fd, "Buffer %zu/%zu: %p\n", i, mBuffers.size(), mBuffers[i]);
     }
 }
 
diff --git a/modules/usbcamera/UsbCamera.cpp b/modules/usbcamera/UsbCamera.cpp
index 82a1145..9d53fc6 100644
--- a/modules/usbcamera/UsbCamera.cpp
+++ b/modules/usbcamera/UsbCamera.cpp
@@ -26,7 +26,7 @@
 #include "Camera.h"
 #include "UsbCamera.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 namespace usb_camera_hal {
 
@@ -313,7 +313,7 @@
     return setTemplate(CAMERA3_TEMPLATE_MANUAL, m.get());
 }
 
-bool UsbCamera::isValidCaptureSettings(const camera_metadata_t* settings) {
+bool UsbCamera::isValidCaptureSettings(const camera_metadata_t* /*settings*/) {
     // TODO: reject settings that cannot be captured
     return true;
 }
diff --git a/modules/usbcamera/UsbCamera.h b/modules/usbcamera/UsbCamera.h
index fe52ade..57017fe 100644
--- a/modules/usbcamera/UsbCamera.h
+++ b/modules/usbcamera/UsbCamera.h
@@ -28,7 +28,7 @@
  */
 class UsbCamera : public Camera {
     public:
-        UsbCamera(int id);
+        explicit UsbCamera(int id);
         ~UsbCamera();
 
     private:
diff --git a/modules/vehicle/Android.mk b/modules/vehicle/Android.mk
index a666bc6..9fd49da 100644
--- a/modules/vehicle/Android.mk
+++ b/modules/vehicle/Android.mk
@@ -19,6 +19,7 @@
 LOCAL_MODULE := vehicle.default
 
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_C_INCLUDES := hardware/libhardware
 LOCAL_SRC_FILES := vehicle.c timeUtil.cpp
 LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
diff --git a/modules/vehicle/vehicle.c b/modules/vehicle/vehicle.c
index a26f27c..2d945fd 100644
--- a/modules/vehicle/vehicle.c
+++ b/modules/vehicle/vehicle.c
@@ -279,10 +279,10 @@
             ALOGD("Value type: FLOAT\nValue: %f\n", data->value.float_value);
             break;
         case VEHICLE_VALUE_TYPE_INT32:
-            ALOGD("Value type: INT32\nValue: %d\n", data->value.int32_value);
+            ALOGD("Value type: INT32\nValue: %" PRId32 "\n", data->value.int32_value);
             break;
         case VEHICLE_VALUE_TYPE_INT64:
-            ALOGD("Value type: INT64\nValue: %lld\n", data->value.int64_value);
+            ALOGD("Value type: INT64\nValue: %" PRId64 "\n", data->value.int64_value);
             break;
         case VEHICLE_VALUE_TYPE_BOOLEAN:
             ALOGD("Value type: BOOLEAN\nValue: %d\n", data->value.boolean_value);
@@ -331,22 +331,6 @@
         event.prop = sub->prop;
         event.timestamp = elapsedRealtimeNano();
         switch (sub->prop) {
-            case VEHICLE_PROPERTY_DRIVING_STATUS:
-                event.value_type = VEHICLE_VALUE_TYPE_INT32;
-                switch ((event.timestamp & 0x30000000)>>28) {
-                    case 0:
-                        event.value.driving_status = VEHICLE_DRIVING_STATUS_UNRESTRICTED;
-                        break;
-                    case 1:
-                        event.value.driving_status = VEHICLE_DRIVING_STATUS_NO_VIDEO;
-                        break;
-                    case 2:
-                        event.value.driving_status = VEHICLE_DRIVING_STATUS_NO_KEYBOARD_INPUT;
-                        break;
-                    default:
-                        event.value.driving_status = VEHICLE_DRIVING_STATUS_NO_CONFIG;
-                }
-                break;
             case VEHICLE_PROPERTY_GEAR_SELECTION:
                 event.value_type = VEHICLE_VALUE_TYPE_INT32;
                 switch ((event.timestamp & 0x30000000)>>28) {
diff --git a/modules/vibrator/Android.bp b/modules/vibrator/Android.bp
new file mode 100644
index 0000000..3c4aebf
--- /dev/null
+++ b/modules/vibrator/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "vibrator.default",
+
+    // HAL module implementation stored in
+    // hw/<VIBRATOR_HARDWARE_MODULE_ID>.default.so
+    relative_install_path: "hw",
+    proprietary: true,
+    include_dirs: ["hardware/libhardware"],
+    srcs: ["vibrator.c"],
+    shared_libs: ["liblog"],
+}
diff --git a/modules/vibrator/vibrator.c b/modules/vibrator/vibrator.c
index 6b3ce57..92c46e2 100644
--- a/modules/vibrator/vibrator.c
+++ b/modules/vibrator/vibrator.c
@@ -21,47 +21,51 @@
 
 #include <malloc.h>
 #include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <math.h>
 
+#define TIMEOUT_STR_LEN         20
+
 static const char THE_DEVICE[] = "/sys/class/timed_output/vibrator/enable";
 
-static int vibra_exists() {
+static bool device_exists(const char *file) {
     int fd;
 
-    fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR));
+    fd = TEMP_FAILURE_RETRY(open(file, O_RDWR));
     if(fd < 0) {
-        ALOGE("Vibrator file does not exist : %d", fd);
-        return 0;
+        return false;
     }
 
     close(fd);
-    return 1;
+    return true;
 }
 
-static int sendit(unsigned int timeout_ms)
+static bool vibra_exists() {
+    return device_exists(THE_DEVICE);
+}
+
+static int write_value(const char *file, const char *value)
 {
     int to_write, written, ret, fd;
 
-    char value[20]; /* large enough for millions of years */
-
-    fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR));
-    if(fd < 0) {
+    fd = TEMP_FAILURE_RETRY(open(file, O_WRONLY));
+    if (fd < 0) {
         return -errno;
     }
 
-    to_write = snprintf(value, sizeof(value), "%u\n", timeout_ms);
+    to_write = strlen(value) + 1;
     written = TEMP_FAILURE_RETRY(write(fd, value, to_write));
-
     if (written == -1) {
         ret = -errno;
     } else if (written != to_write) {
         /* even though EAGAIN is an errno value that could be set
            by write() in some cases, none of them apply here.  So, this return
            value can be clearly identified when debugging and suggests the
-           caller that it may try to call vibraror_on() again */
+           caller that it may try to call vibrator_on() again */
         ret = -EAGAIN;
     } else {
         ret = 0;
@@ -73,6 +77,14 @@
     return ret;
 }
 
+static int sendit(unsigned int timeout_ms)
+{
+    char value[TIMEOUT_STR_LEN]; /* large enough for millions of years */
+
+    snprintf(value, sizeof(value), "%u", timeout_ms);
+    return write_value(THE_DEVICE, value);
+}
+
 static int vibra_on(vibrator_device_t* vibradev __unused, unsigned int timeout_ms)
 {
     /* constant on, up to maximum allowed time */
@@ -84,6 +96,47 @@
     return sendit(0);
 }
 
+static const char LED_DEVICE[] = "/sys/class/leds/vibrator";
+
+static int write_led_file(const char *file, const char *value)
+{
+    char file_str[50];
+
+    snprintf(file_str, sizeof(file_str), "%s/%s", LED_DEVICE, file);
+    return write_value(file_str, value);
+}
+
+static bool vibra_led_exists()
+{
+    int fd;
+    char file_str[50];
+
+    snprintf(file_str, sizeof(file_str), "%s/%s", LED_DEVICE, "activate");
+    return device_exists(file_str);
+}
+
+static int vibra_led_on(vibrator_device_t* vibradev __unused, unsigned int timeout_ms)
+{
+    int ret;
+    char value[TIMEOUT_STR_LEN]; /* large enough for millions of years */
+
+    ret = write_led_file("state", "1");
+    if (ret)
+        return ret;
+
+    snprintf(value, sizeof(value), "%u\n", timeout_ms);
+    ret = write_led_file("duration", value);
+    if (ret)
+        return ret;
+
+    return write_led_file("activate", "1");
+}
+
+static int vibra_led_off(vibrator_device_t* vibradev __unused)
+{
+    return write_led_file("activate", "0");
+}
+
 static int vibra_close(hw_device_t *device)
 {
     free(device);
@@ -92,7 +145,15 @@
 
 static int vibra_open(const hw_module_t* module, const char* id __unused,
                       hw_device_t** device __unused) {
-    if (!vibra_exists()) {
+    bool use_led;
+
+    if (vibra_exists()) {
+        ALOGD("Vibrator using timed_output");
+        use_led = false;
+    } else if (vibra_led_exists()) {
+        ALOGD("Vibrator using LED trigger");
+        use_led = true;
+    } else {
         ALOGE("Vibrator device does not exist. Cannot start vibrator");
         return -ENODEV;
     }
@@ -109,8 +170,13 @@
     vibradev->common.version = HARDWARE_DEVICE_API_VERSION(1,0);
     vibradev->common.close = vibra_close;
 
-    vibradev->vibrator_on = vibra_on;
-    vibradev->vibrator_off = vibra_off;
+    if (use_led) {
+        vibradev->vibrator_on = vibra_led_on;
+        vibradev->vibrator_off = vibra_led_off;
+    } else {
+        vibradev->vibrator_on = vibra_on;
+        vibradev->vibrator_off = vibra_off;
+    }
 
     *device = (hw_device_t *) vibradev;
 
diff --git a/modules/vr/Android.mk b/modules/vr/Android.mk
index 43c8e92..e04c0da 100644
--- a/modules/vr/Android.mk
+++ b/modules/vr/Android.mk
@@ -18,6 +18,7 @@
 
 LOCAL_MODULE := vr.default
 LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_SRC_FILES := vr.c
 LOCAL_SHARED_LIBRARIES := libcutils
 LOCAL_MODULE_TAGS := optional
diff --git a/tests/camera2/Android.mk b/tests/camera2/Android.mk
index e45f467..e4f9640 100644
--- a/tests/camera2/Android.mk
+++ b/tests/camera2/Android.mk
@@ -25,10 +25,12 @@
 	libgui \
 	libsync \
 	libui \
-	libdl
+	libdl \
+	android.hardware.camera.device@3.2
 
 LOCAL_C_INCLUDES += \
 	system/media/camera/include \
+	system/media/private/camera/include \
 	frameworks/av/include/ \
 	frameworks/av/services/camera/libcameraservice \
 	frameworks/native/include \
diff --git a/tests/camera2/CameraModuleFixture.h b/tests/camera2/CameraModuleFixture.h
index 661c693..b0d49e2 100644
--- a/tests/camera2/CameraModuleFixture.h
+++ b/tests/camera2/CameraModuleFixture.h
@@ -35,7 +35,7 @@
 template <bool InfoQuirk = false>
 struct CameraModuleFixture {
 
-    CameraModuleFixture(int CameraID = -1) {
+    explicit CameraModuleFixture(int CameraID = -1) {
         TEST_EXTENSION_FORKING_CONSTRUCTOR;
 
         mCameraID = CameraID;
@@ -74,7 +74,6 @@
     void TearDown() {
         TEST_EXTENSION_FORKING_TEAR_DOWN;
 
-        delete mModule;
         TearDownMixin();
 
         /* important: device must be destructed before closing module,
@@ -85,6 +84,7 @@
             ASSERT_EQ(0, HWModuleHelpers::closeModule(mModule->getDso()))
                 << "Failed to close camera HAL module";
         }
+        delete mModule;
     }
 
     void CreateCamera(int cameraID, /*out*/ sp<CameraDeviceBase> *device) {
@@ -98,7 +98,7 @@
             case CAMERA_DEVICE_API_VERSION_3_0:
             case CAMERA_DEVICE_API_VERSION_3_1:
             case CAMERA_DEVICE_API_VERSION_3_2:
-                *device = new Camera3Device(cameraID);
+                *device = new Camera3Device(String8::format("%d", cameraID));
                 break;
             default:
                 device->clear();
diff --git a/tests/camera2/CameraMultiStreamTests.cpp b/tests/camera2/CameraMultiStreamTests.cpp
index eb64db1..f4aeab7 100644
--- a/tests/camera2/CameraMultiStreamTests.cpp
+++ b/tests/camera2/CameraMultiStreamTests.cpp
@@ -334,7 +334,7 @@
             int height,
             const sp<CameraDeviceBase>& device,
             CameraStreamParams param = DEFAULT_STREAM_PARAMETERS,
-            sp<Surface> surface = NULL,
+            const sp<Surface>& surface = NULL,
             bool useCpuConsumer = true) {
         param.mFormat = MapAutoFormat(param.mFormat);
         return new CameraStream(width, height, device,
diff --git a/tests/camera2/CameraStreamFixture.h b/tests/camera2/CameraStreamFixture.h
index bf7fb42..92ff05b 100644
--- a/tests/camera2/CameraStreamFixture.h
+++ b/tests/camera2/CameraStreamFixture.h
@@ -71,7 +71,7 @@
     : public CameraModuleFixture</*InfoQuirk*/true> {
 
 public:
-    CameraStreamFixture(CameraStreamParams p)
+    explicit CameraStreamFixture(CameraStreamParams p)
     : CameraModuleFixture(TestSettings::DeviceId()) {
         TEST_EXTENSION_FORKING_CONSTRUCTOR;
 
diff --git a/tests/camera2/camera2_utils.cpp b/tests/camera2/camera2_utils.cpp
index c63c32a..dab0ae9 100644
--- a/tests/camera2/camera2_utils.cpp
+++ b/tests/camera2/camera2_utils.cpp
@@ -176,7 +176,7 @@
 }
 
 status_t MetadataQueue::freeBuffers(List<camera_metadata_t*>::iterator start,
-                                    List<camera_metadata_t*>::iterator end) {
+                                    const List<camera_metadata_t*>::iterator& end) {
     while (start != end) {
         free_camera_metadata(*start);
         start = mStreamSlot.erase(start);
diff --git a/tests/camera2/camera2_utils.h b/tests/camera2/camera2_utils.h
index ab1fcfb..274ee76 100644
--- a/tests/camera2/camera2_utils.h
+++ b/tests/camera2/camera2_utils.h
@@ -65,7 +65,7 @@
 
   private:
     status_t freeBuffers(List<camera_metadata_t*>::iterator start,
-                         List<camera_metadata_t*>::iterator end);
+                         const List<camera_metadata_t*>::iterator& end);
 
     camera2_device_t *mDevice;
 
@@ -166,7 +166,7 @@
  */
 class StreamAdapter: public camera2_stream_ops {
   public:
-    StreamAdapter(sp<IGraphicBufferProducer> consumer);
+    explicit StreamAdapter(sp<IGraphicBufferProducer> consumer);
 
     ~StreamAdapter();
 
diff --git a/tests/fingerprint/Android.bp b/tests/fingerprint/Android.bp
new file mode 100644
index 0000000..7de3dee
--- /dev/null
+++ b/tests/fingerprint/Android.bp
@@ -0,0 +1,14 @@
+cc_test {
+    name: "fingerprint_tests",
+    srcs: ["fingerprint_tests.cpp"],
+
+    shared_libs: [
+        "liblog",
+        "libhardware",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+}
diff --git a/tests/fingerprint/Android.mk b/tests/fingerprint/Android.mk
deleted file mode 100644
index 4f03c39..0000000
--- a/tests/fingerprint/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    fingerprint_tests.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-    liblog \
-    libhardware \
-
-#LOCAL_C_INCLUDES += \
-#    system/media/camera/include \
-
-LOCAL_CFLAGS += -Wall -Wextra
-
-LOCAL_MODULE:= fingerprint_tests
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_NATIVE_TEST)
diff --git a/tests/hardware/struct-offset.cpp b/tests/hardware/struct-offset.cpp
index 10c0895..7f7f2e0 100644
--- a/tests/hardware/struct-offset.cpp
+++ b/tests/hardware/struct-offset.cpp
@@ -116,7 +116,9 @@
     CHECK_MEMBER_AT(sensors_poll_device_1_t, batch, 76, 144);
     CHECK_MEMBER_AT(sensors_poll_device_1_t, flush, 80, 152);
     CHECK_MEMBER_AT(sensors_poll_device_1_t, inject_sensor_data, 84, 160);
-    CHECK_MEMBER_AT(sensors_poll_device_1_t, reserved_procs, 88, 168);
+    CHECK_MEMBER_AT(sensors_poll_device_1_t, register_direct_channel, 88, 168);
+    CHECK_MEMBER_AT(sensors_poll_device_1_t, config_direct_report, 92, 176);
+    CHECK_MEMBER_AT(sensors_poll_device_1_t, reserved_procs, 96, 184);
 
     //Types defined in fb.h
     CHECK_MEMBER_AT(framebuffer_device_t, common, 0, 0);
diff --git a/tests/hwc/cnativewindow.c b/tests/hwc/cnativewindow.c
index 5c16afb..5b1d78e 100644
--- a/tests/hwc/cnativewindow.c
+++ b/tests/hwc/cnativewindow.c
@@ -37,7 +37,7 @@
 static int trace_level = 1;
 
 #define _TRACE(n,fmt...) \
-	do { if (trace_level >= n) fprintf(stderr, "CNW: " fmt); } while (0)
+	do { if (trace_level >= (n)) fprintf(stderr, "CNW: " fmt); } while (0)
 
 #define ERROR(fmt...) _TRACE(0, fmt)
 #define INFO(fmt...) _TRACE(1, fmt)
diff --git a/tests/input/evdev/Android.mk b/tests/input/evdev/Android.mk
index 3aeb2f8..b892a7f 100644
--- a/tests/input/evdev/Android.mk
+++ b/tests/input/evdev/Android.mk
@@ -2,7 +2,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_C_INCLUDES += hardware/libhardware/modules/input/evdev
-LOCAL_C_INCLUDES += $(TOP)/external/gmock/include
 
 LOCAL_SRC_FILES:= \
     BitUtils_test.cpp \
diff --git a/tests/input/evdev/InputHub_test.cpp b/tests/input/evdev/InputHub_test.cpp
index 64671ff..3d62152 100644
--- a/tests/input/evdev/InputHub_test.cpp
+++ b/tests/input/evdev/InputHub_test.cpp
@@ -50,9 +50,9 @@
         mInputCb(kNoopInputCb), mDeviceAddedCb(kNoopDeviceCb), mDeviceRemovedCb(kNoopDeviceCb) {}
     virtual ~TestInputCallback() = default;
 
-    void setInputCallback(InputCbFunc cb) { mInputCb = cb; }
-    void setDeviceAddedCallback(DeviceCbFunc cb) { mDeviceAddedCb = cb; }
-    void setDeviceRemovedCallback(DeviceCbFunc cb) { mDeviceRemovedCb = cb; }
+    void setInputCallback(const InputCbFunc& cb) { mInputCb = cb; }
+    void setDeviceAddedCallback(const DeviceCbFunc& cb) { mDeviceAddedCb = cb; }
+    void setDeviceRemovedCallback(const DeviceCbFunc& cb) { mDeviceRemovedCb = cb; }
 
     virtual void onInputEvent(const std::shared_ptr<InputDeviceNode>& node, InputEvent& event,
             nsecs_t event_time) override {
diff --git a/tests/input/evdev/TestHelpers.h b/tests/input/evdev/TestHelpers.h
index 461db04..d26adfb 100644
--- a/tests/input/evdev/TestHelpers.h
+++ b/tests/input/evdev/TestHelpers.h
@@ -42,7 +42,7 @@
  */
 class TempFile {
 public:
-    TempFile(const char* path);
+    explicit TempFile(const char* path);
     ~TempFile();
 
     // No copy or assign
diff --git a/tests/keymaster/keymaster_test.cpp b/tests/keymaster/keymaster_test.cpp
index 6266d40..3040a5c 100644
--- a/tests/keymaster/keymaster_test.cpp
+++ b/tests/keymaster/keymaster_test.cpp
@@ -41,7 +41,7 @@
 
 class UniqueBlob : public UniquePtr<uint8_t[]> {
 public:
-    UniqueBlob(size_t length) :
+    explicit UniqueBlob(size_t length) :
             mLength(length) {
     }
 
diff --git a/tests/nusensors/Android.bp b/tests/nusensors/Android.bp
new file mode 100644
index 0000000..e923468
--- /dev/null
+++ b/tests/nusensors/Android.bp
@@ -0,0 +1,10 @@
+cc_binary {
+    name: "test-nusensors",
+
+    srcs: ["nusensors.cpp"],
+
+    shared_libs: [
+        "libcutils",
+        "libhardware",
+    ],
+}
diff --git a/tests/nusensors/Android.mk b/tests/nusensors/Android.mk
deleted file mode 100644
index ef49096..0000000
--- a/tests/nusensors/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	nusensors.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils libhardware
-
-LOCAL_MODULE:= test-nusensors
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
diff --git a/tests/vehicle/README b/tests/vehicle/README
index b8fc7d4..42d2210 100644
--- a/tests/vehicle/README
+++ b/tests/vehicle/README
@@ -49,13 +49,13 @@
 $ mmm hardware/libhardware
 
 This will generate the following binaries that we care about:
-i) out/target/product/XXX/system/lib/hw/vehicle.default.so
+i) out/target/product/XXX/vendor/lib/hw/vehicle.default.so
 ii) out/target/product/XXX/data/nativetest/vehicle_tests
 iii) out/target/product/XXX/system/bin/vehicle-hal-tool
 
 The location for the first shared library would be:
-$ adb push out/target/product/XXX/system/lib/hw/vehicle.default.so
-/system/lib/hw
+$ adb push out/target/product/XXX/vendor/lib/hw/vehicle.default.so
+/vendor/lib/hw
 You can also use 'adb sync' if you like, although this is the easiest least
 hassle way of putting it in place.
 
diff --git a/tests/vehicle/vehicle-hal-tool.c b/tests/vehicle/vehicle-hal-tool.c
old mode 100755
new mode 100644
index c93790a..e85df62
--- a/tests/vehicle/vehicle-hal-tool.c
+++ b/tests/vehicle/vehicle-hal-tool.c
@@ -98,6 +98,7 @@
             memcpy(ascii_out, data->value.str_value.data, data->value.str_value.len);
             ascii_out[data->value.str_value.len] = '\0';
             printf("Value Type: STRING %s\n", ascii_out);
+            free(ascii_out);
             break;
         case VEHICLE_VALUE_TYPE_BYTES:
             printf("Value type: BYTES\n Size: %d", data->value.bytes_value.len);