Merge commit 'b28bdeefe25a69d9dd2d9c7adfa11b9aadb7baad' into manual_merge_b28bdeef

Bug: 37512442
Bug: 37159108
Test: it builds

Change-Id: I96a78d45e9f63f82a0b0b904c1ecdcd8fe4ff564
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/include/hardware/audio.h b/include/hardware/audio.h
index c95ad09..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;
 
diff --git a/include/hardware/audio_alsaops.h b/include/hardware/audio_alsaops.h
index f83941e..6a17a35 100644
--- a/include/hardware/audio_alsaops.h
+++ b/include/hardware/audio_alsaops.h
@@ -38,7 +38,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:
@@ -73,7 +73,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/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/fingerprint.h b/include/hardware/fingerprint.h
index b4465ba..86ced9b 100644
--- a/include/hardware/fingerprint.h
+++ b/include/hardware/fingerprint.h
@@ -23,6 +23,7 @@
 #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 {
@@ -51,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;
 
@@ -69,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;
 
@@ -85,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 */
@@ -207,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.
      */
@@ -222,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/gralloc1.h b/include/hardware/gralloc1.h
index a1a2d69..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 */
@@ -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/hwcomposer.h b/include/hardware/hwcomposer.h
index 7eca7c1..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.
diff --git a/include/hardware/hwcomposer2.h b/include/hardware/hwcomposer2.h
index 35eedb0..d5a0d6f 100644
--- a/include/hardware/hwcomposer2.h
+++ b/include/hardware/hwcomposer2.h
@@ -94,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 */
@@ -335,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";
     }
 }
@@ -551,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)
 
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/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/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 322abe6..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,749 +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
- * wake-up sensor: yes
- *
- * 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.
- *
- * It is recommended to implement this type as wake up sensor.
- *
- */
-#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.
@@ -879,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;
 
 /**
@@ -913,7 +223,7 @@
 } sensors_vec_t;
 
 /**
- * uncalibrated gyroscope and magnetometer event data
+ * uncalibrated accelerometer, gyroscope and magnetometer event data
  */
 typedef struct {
   union {
@@ -980,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.
@@ -1106,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;
 
@@ -1228,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;
 
@@ -1280,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
@@ -1336,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);
@@ -1381,7 +649,61 @@
      */
     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;
 
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/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
index 80cab19..84daead 100644
--- a/modules/audio/Android.bp
+++ b/modules/audio/Android.bp
@@ -21,11 +21,12 @@
 cc_library_shared {
     name: "audio.primary.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["audio_hw.c"],
     shared_libs: [
         "liblog",
     ],
-    cflags: ["-Wno-unused-parameter"],
+    cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"],
 }
 
 // The stub audio HAL module, identical to the default audio hal, but with
@@ -37,11 +38,12 @@
 cc_library_shared {
     name: "audio.stub.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["audio_hw.c"],
     shared_libs: [
         "liblog",
     ],
-    cflags: ["-Wno-unused-parameter"],
+    cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"],
 }
 
 // The stub audio policy HAL module that can be used as a skeleton for
@@ -49,9 +51,10 @@
 cc_library_shared {
     name: "audio_policy.stub",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["audio_policy.c"],
     shared_libs: [
         "liblog",
     ],
-    cflags: ["-Wno-unused-parameter"],
+    cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"],
 }
diff --git a/modules/audio/audio_hw.c b/modules/audio/audio_hw.c
index 3c288ca..8f73f11 100644
--- a/modules/audio/audio_hw.c
+++ b/modules/audio/audio_hw.c
@@ -300,11 +300,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;
 
@@ -328,11 +326,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,
@@ -427,11 +420,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;
 
@@ -453,11 +443,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,
@@ -486,7 +471,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/camera/3_0/Android.mk b/modules/camera/3_0/Android.mk
new file mode 100644
index 0000000..ae68ed5
--- /dev/null
+++ b/modules/camera/3_0/Android.mk
@@ -0,0 +1,45 @@
+# 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.
+
+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)
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 100%
rename from modules/camera/Camera.h
rename to modules/camera/3_0/Camera.h
diff --git a/modules/camera/CameraHAL.cpp b/modules/camera/3_0/CameraHAL.cpp
similarity index 100%
rename from modules/camera/CameraHAL.cpp
rename to modules/camera/3_0/CameraHAL.cpp
diff --git a/modules/camera/CameraHAL.h b/modules/camera/3_0/CameraHAL.h
similarity index 100%
rename from modules/camera/CameraHAL.h
rename to modules/camera/3_0/CameraHAL.h
diff --git a/modules/camera/ExampleCamera.cpp b/modules/camera/3_0/ExampleCamera.cpp
similarity index 100%
rename from modules/camera/ExampleCamera.cpp
rename to modules/camera/3_0/ExampleCamera.cpp
diff --git a/modules/camera/ExampleCamera.h b/modules/camera/3_0/ExampleCamera.h
similarity index 100%
rename from modules/camera/ExampleCamera.h
rename to modules/camera/3_0/ExampleCamera.h
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 100%
rename from modules/camera/VendorTags.cpp
rename to modules/camera/3_0/VendorTags.cpp
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
index 4ee5fb1..b139492 100644
--- a/modules/consumerir/Android.bp
+++ b/modules/consumerir/Android.bp
@@ -15,6 +15,7 @@
 cc_library_shared {
     name: "consumerir.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["consumerir.c"],
     shared_libs: [
         "liblog",
diff --git a/modules/fingerprint/Android.bp b/modules/fingerprint/Android.bp
index a66f9f9..ba749e4 100644
--- a/modules/fingerprint/Android.bp
+++ b/modules/fingerprint/Android.bp
@@ -15,6 +15,7 @@
 cc_library_shared {
     name: "fingerprint.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["fingerprint.c"],
     shared_libs: ["liblog"],
 }
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index 6b6e60d..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 := 	\
diff --git a/modules/gralloc/gralloc.cpp b/modules/gralloc/gralloc.cpp
index f8d3c78..07bbfba 100644
--- a/modules/gralloc/gralloc.cpp
+++ b/modules/gralloc/gralloc.cpp
@@ -209,6 +209,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 297cafd..fd4e90d 100644
--- a/modules/hwcomposer/hwcomposer.cpp
+++ b/modules/hwcomposer/hwcomposer.cpp
@@ -37,18 +37,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,
     }
 };
 
@@ -67,8 +67,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]);
@@ -78,16 +78,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/local_time/Android.bp b/modules/local_time/Android.bp
index df32325..643afa5 100644
--- a/modules/local_time/Android.bp
+++ b/modules/local_time/Android.bp
@@ -24,6 +24,7 @@
 cc_library_shared {
     name: "local_time.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["local_time_hw.c"],
     shared_libs: [
         "liblog",
diff --git a/modules/local_time/local_time_hw.c b/modules/local_time/local_time_hw.c
index 4b21656..b38d8a5 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
index fc73761..90d2a28 100644
--- a/modules/nfc-nci/Android.bp
+++ b/modules/nfc-nci/Android.bp
@@ -15,6 +15,7 @@
 cc_library_shared {
     name: "nfc_nci.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["nfc_nci_example.c"],
     shared_libs: [
         "liblog",
diff --git a/modules/nfc-nci/nfc_nci_example.c b/modules/nfc-nci/nfc_nci_example.c
index cdfd7d7..f3f60f6 100644
--- a/modules/nfc-nci/nfc_nci_example.c
+++ b/modules/nfc-nci/nfc_nci_example.c
@@ -23,44 +23,61 @@
 #include <hardware/nfc.h>
 
 /*
+ * 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
index 53ab309..10dc2c1 100644
--- a/modules/nfc/Android.bp
+++ b/modules/nfc/Android.bp
@@ -15,6 +15,7 @@
 cc_library_shared {
     name: "nfc.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["nfc_pn544_example.c"],
     shared_libs: [
         "liblog",
diff --git a/modules/power/Android.bp b/modules/power/Android.bp
index 2b86c8b..f4c74ce 100644
--- a/modules/power/Android.bp
+++ b/modules/power/Android.bp
@@ -15,6 +15,7 @@
 cc_library_shared {
     name: "power.default",
     relative_install_path: "hw",
+    proprietary: true,
     srcs: ["power.c"],
     shared_libs: ["liblog"],
 }
diff --git a/modules/radio/radio_hal_tool.c b/modules/radio/radio_hal_tool.c
index baa2efe..0117f28 100644
--- a/modules/radio/radio_hal_tool.c
+++ b/modules/radio/radio_hal_tool.c
@@ -133,7 +133,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 298bf75..964a8b6 100644
--- a/modules/radio/radio_hw.c
+++ b/modules/radio/radio_hw.c
@@ -51,7 +51,7 @@
     .bands = {
         {
             .type = RADIO_BAND_FM,
-            .antenna_connected = false,
+            .antenna_connected = true,
             .lower_limit = 87900,
             .upper_limit = 107900,
             .num_spacings = 1,
@@ -213,6 +213,7 @@
     *metadata = NULL;
 
     ret = radio_metadata_allocate(metadata, tuner->program.channel, 0);
+
     if (ret != 0)
         return ret;
 
@@ -224,14 +225,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;
     }
 
@@ -359,6 +360,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;
@@ -385,6 +387,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;
@@ -397,12 +400,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)
@@ -411,6 +409,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;
@@ -422,7 +422,6 @@
                         event.type = RADIO_EVENT_METADATA;
                         event.metadata = metadata;
                     }
-                    send_meta_data = true;
                 } break;
 
                 case CMD_CANCEL: {
@@ -506,6 +505,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);
 
@@ -618,7 +621,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/dynamic_sensor/Android.mk b/modules/sensors/dynamic_sensor/Android.mk
new file mode 100644
index 0000000..348542a
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/Android.mk
@@ -0,0 +1,130 @@
+# 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
+# host test is targeting linux host only
+LOCAL_MODULE_HOST_OS := linux
+
+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
+# host test is targeting linux host only
+LOCAL_MODULE_HOST_OS := linux
+
+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..c51e912
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
@@ -0,0 +1,238 @@
+/*
+ * 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),
+              mLooper(new Looper(true /*allowNonCallback*/)), mInotifyFd(-1) {
+    if (mLooper == nullptr) {
+        return;
+    }
+
+    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);
+    if (wd < 0 || !mLooper->addFd(mInotifyFd, POLL_IDENT, Looper::EVENT_INPUT, nullptr, nullptr)) {
+        ::close(mInotifyFd);
+        mInotifyFd = -1;
+        ALOGE("Cannot setup watch on dir %s", path.c_str());
+        return;
+    }
+
+    // mLooper != null && mInotifyFd added to looper
+    run("ddad_file");
+}
+
+FileConnectionDetector::~FileConnectionDetector() {
+    if (mInotifyFd > 0) {
+        requestExit();
+        mLooper->wake();
+        join();
+        ::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);
+}
+
+void FileConnectionDetector::handleInotifyData(ssize_t len, const char *data) {
+    const char *dataEnd = data + len;
+    const struct inotify_event *ev;
+
+    // inotify adds paddings to guarantee the next read is aligned
+    for (; data < dataEnd; data += sizeof(struct inotify_event) + ev->len) {
+        ev = reinterpret_cast<const struct inotify_event*>(data);
+        if (ev->mask & IN_ISDIR) {
+            continue;
+        }
+
+        const std::string name(ev->name);
+        if (matches(name)) {
+            if (ev->mask & IN_CREATE) {
+                mDaemon->onConnectionChange(getFullName(name), true /*connected*/);
+            }
+            if (ev->mask & IN_DELETE) {
+                mDaemon->onConnectionChange(getFullName(name), false /*connected*/);
+            }
+        }
+    }
+}
+
+bool FileConnectionDetector::readInotifyData() {
+    struct {
+        struct inotify_event ev;
+        char padding[NAME_MAX + 1];
+    } buffer;
+
+    bool ret = true;
+    while (true) {
+        ssize_t len = ::read(mInotifyFd, &buffer, sizeof(buffer));
+        if (len == -1 && errno == EAGAIN) {
+            // no more data
+            break;
+        } else if (len > static_cast<ssize_t>(sizeof(struct inotify_event))) {
+            handleInotifyData(len, reinterpret_cast<char*>(&buffer));
+        } else if (len < 0) {
+            ALOGE("read error: %s", ::strerror(errno));
+            ret = false;
+            break;
+        } else {
+            // 0 <= len <= sizeof(struct inotify_event)
+            ALOGE("read return %zd, shorter than inotify_event size %zu",
+                  len, sizeof(struct inotify_event));
+            ret = false;
+            break;
+        }
+    }
+    return ret;
+}
+
+bool FileConnectionDetector::threadLoop() {
+    Looper::setForThread(mLooper);
+    processExistingFiles();
+    while(!Thread::exitPending()) {
+        int ret = mLooper->pollOnce(-1);
+
+        if (ret != Looper::POLL_WAKE && ret != POLL_IDENT) {
+            ALOGE("Unexpected value %d from pollOnce, quit", ret);
+            requestExit();
+            break;
+        }
+
+        if (ret == POLL_IDENT) {
+            if (!readInotifyData()) {
+                requestExit();
+            }
+        }
+    }
+
+    mLooper->removeFd(mInotifyFd);
+    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..0ee1df2
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.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_CONNECTION_DETECTOR_H
+#define ANDROID_SENSORHAL_EXT_CONNECTION_DETECTOR_H
+
+#include "BaseDynamicSensorDaemon.h"
+#include <utils/Thread.h>
+#include <utils/Looper.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:
+    static constexpr int POLL_IDENT = 1;
+    // implement virtual of Thread
+    virtual bool threadLoop();
+
+    bool matches(const std::string &name) const;
+    void processExistingFiles() const;
+    void handleInotifyData(ssize_t len, const char *data);
+    bool readInotifyData();
+    std::string getFullName(const std::string name) const;
+
+    std::string mPath;
+    std::regex mRegex;
+    sp<Looper> mLooper;
+    int mInotifyFd;
+};
+
+} // 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..8aa4cf9
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDevice.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 "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));
+    // offset +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) {
+    // 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);
+
+    if (!HidRawDevice::isValid()) {
+        return;
+    }
+
+    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/tv_input/Android.bp b/modules/tv_input/Android.bp
index beac132..509198d 100644
--- a/modules/tv_input/Android.bp
+++ b/modules/tv_input/Android.bp
@@ -15,6 +15,7 @@
 cc_library_shared {
     name: "tv_input.default",
     relative_install_path: "hw",
+    proprietary: true,
     shared_libs: [
         "libcutils",
         "liblog",
diff --git a/modules/tv_input/tv_input.cpp b/modules/tv_input/tv_input.cpp
index f93cb20..4c42518 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 500a982..0324da8 100644
--- a/modules/usbcamera/Camera.cpp
+++ b/modules/usbcamera/Camera.cpp
@@ -491,9 +491,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/CameraHAL.cpp b/modules/usbcamera/CameraHAL.cpp
index eec1044..1a5eb3a 100644
--- a/modules/usbcamera/CameraHAL.cpp
+++ b/modules/usbcamera/CameraHAL.cpp
@@ -69,7 +69,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());
 }
 
@@ -130,29 +130,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 80f18c8..6188ede 100644
--- a/modules/usbcamera/HotplugThread.cpp
+++ b/modules/usbcamera/HotplugThread.cpp
@@ -40,6 +40,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/Stream.cpp b/modules/usbcamera/Stream.cpp
index 45e7fc2..d418798 100644
--- a/modules/usbcamera/Stream.cpp
+++ b/modules/usbcamera/Stream.cpp
@@ -172,10 +172,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 ec949ae..65cbec9 100644
--- a/modules/usbcamera/UsbCamera.cpp
+++ b/modules/usbcamera/UsbCamera.cpp
@@ -316,7 +316,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/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 78545af..66e29c0 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
index f9afd45..3c4aebf 100644
--- a/modules/vibrator/Android.bp
+++ b/modules/vibrator/Android.bp
@@ -18,6 +18,7 @@
     // 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/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
deleted file mode 100644
index e45f467..0000000
--- a/tests/camera2/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	camera2_utils.cpp \
-	main.cpp \
-	CameraMetadataTests.cpp \
-	CameraModuleTests.cpp \
-	CameraStreamTests.cpp \
-	CameraFrameTests.cpp \
-	CameraBurstTests.cpp \
-	CameraMultiStreamTests.cpp\
-	ForkedTests.cpp \
-	TestForkerEventListener.cpp \
-	TestSettings.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-	liblog \
-	libutils \
-	libcutils \
-	libhardware \
-	libcamera_metadata \
-	libcameraservice \
-	libcamera_client \
-	libgui \
-	libsync \
-	libui \
-	libdl
-
-LOCAL_C_INCLUDES += \
-	system/media/camera/include \
-	frameworks/av/include/ \
-	frameworks/av/services/camera/libcameraservice \
-	frameworks/native/include \
-
-LOCAL_CFLAGS += -Wall -Wextra
-LOCAL_MODULE:= camera2_test
-LOCAL_MODULE_STEM_32 := camera2_test
-LOCAL_MODULE_STEM_64 := camera2_test64
-LOCAL_MULTILIB := both
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_NATIVE_TEST)
diff --git a/tests/camera2/CameraBurstTests.cpp b/tests/camera2/CameraBurstTests.cpp
deleted file mode 100644
index 198c0c1..0000000
--- a/tests/camera2/CameraBurstTests.cpp
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * 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.
- */
-
-#include <gtest/gtest.h>
-#include <inttypes.h>
-
-#define LOG_TAG "CameraBurstTest"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#include <cmath>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-#define CAMERA_FRAME_TIMEOUT    1000000000LL //nsecs (1 secs)
-#define CAMERA_HEAP_COUNT       2 //HALBUG: 1 means registerBuffers fails
-#define CAMERA_BURST_DEBUGGING  0
-#define CAMERA_FRAME_BURST_COUNT 10
-
-/* constants for the exposure test */
-#define CAMERA_EXPOSURE_DOUBLE  2
-#define CAMERA_EXPOSURE_DOUBLING_THRESHOLD 1.0f
-#define CAMERA_EXPOSURE_DOUBLING_COUNT 4
-#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
-#define CAMERA_EXPOSURE_STARTING 100000 // 1/10ms, up to 51.2ms with 10 steps
-
-#define USEC 1000LL        // in ns
-#define MSEC 1000000LL     // in ns
-#define SEC  1000000000LL  // in ns
-
-#if CAMERA_BURST_DEBUGGING
-#define dout std::cout
-#else
-#define dout if (0) std::cout
-#endif
-
-#define WARN_UNLESS(condition) if(!(condition)) std::cerr << "Warning: "
-#define WARN_LE(exp, act) WARN_UNLESS((exp) <= (act))
-#define WARN_LT(exp, act) WARN_UNLESS((exp) < (act))
-#define WARN_GT(exp, act) WARN_UNLESS((exp) > (act))
-
-using namespace android;
-using namespace android::camera2;
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-static CameraStreamParams STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_EXPOSURE_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-class CameraBurstTest
-    : public ::testing::Test,
-      public CameraStreamFixture {
-
-public:
-    CameraBurstTest() : CameraStreamFixture(STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        if (HasFatalFailure()) {
-            return;
-        }
-
-        CreateStream();
-    }
-
-    ~CameraBurstTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-
-        if (mDevice.get()) {
-            mDevice->waitUntilDrained();
-        }
-        DeleteStream();
-    }
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-
-    /* this assumes the format is YUV420sp or flexible YUV */
-    long long TotalBrightness(const CpuConsumer::LockedBuffer& imgBuffer,
-                              int *underexposed,
-                              int *overexposed) const {
-
-        const uint8_t* buf = imgBuffer.data;
-        size_t stride = imgBuffer.stride;
-
-        /* iterate over the Y plane only */
-        long long acc = 0;
-
-        *underexposed = 0;
-        *overexposed = 0;
-
-        for (size_t y = 0; y < imgBuffer.height; ++y) {
-            for (size_t x = 0; x < imgBuffer.width; ++x) {
-                const uint8_t p = buf[y * stride + x];
-
-                if (p == 0) {
-                    if (underexposed) {
-                        ++*underexposed;
-                    }
-                    continue;
-                } else if (p == 255) {
-                    if (overexposed) {
-                        ++*overexposed;
-                    }
-                    continue;
-                }
-
-                acc += p;
-            }
-        }
-
-        return acc;
-    }
-
-    // Parses a comma-separated string list into a Vector
-    template<typename T>
-    void ParseList(const char *src, Vector<T> &list) {
-        std::istringstream s(src);
-        while (!s.eof()) {
-            char c = s.peek();
-            if (c == ',' || c == ' ') {
-                s.ignore(1, EOF);
-                continue;
-            }
-            T val;
-            s >> val;
-            list.push_back(val);
-        }
-    }
-
-};
-
-TEST_F(CameraBurstTest, ManualExposureControl) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    // Range of valid exposure times, in nanoseconds
-    int64_t minExp, maxExp;
-    {
-        camera_metadata_ro_entry exposureTimeRange =
-            GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
-
-        ASSERT_EQ(2u, exposureTimeRange.count);
-        minExp = exposureTimeRange.data.i64[0];
-        maxExp = exposureTimeRange.data.i64[1];
-    }
-
-    dout << "Min exposure is " << minExp;
-    dout << " max exposure is " << maxExp << std::endl;
-
-    // Calculate some set of valid exposure times for each request
-    int64_t exposures[CAMERA_FRAME_BURST_COUNT];
-    exposures[0] = CAMERA_EXPOSURE_STARTING;
-    for (int i = 1; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        exposures[i] = exposures[i-1] * CAMERA_EXPOSURE_DOUBLE;
-    }
-    // Our calculated exposure times should be in [minExp, maxExp]
-    EXPECT_LE(minExp, exposures[0])
-        << "Minimum exposure range is too high, wanted at most "
-        << exposures[0] << "ns";
-    EXPECT_GE(maxExp, exposures[CAMERA_FRAME_BURST_COUNT-1])
-        << "Maximum exposure range is too low, wanted at least "
-        << exposures[CAMERA_FRAME_BURST_COUNT-1] << "ns";
-
-    // Create a preview request, turning off all 3A
-    CameraMetadata previewRequest;
-    ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                                                &previewRequest));
-    {
-        Vector<int32_t> outputStreamIds;
-        outputStreamIds.push(mStreamId);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                                            outputStreamIds));
-
-        // Disable all 3A routines
-        uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_CONTROL_MODE,
-                                            &cmOff, 1));
-
-        int requestId = 1;
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
-                                            &requestId, 1));
-
-        if (CAMERA_BURST_DEBUGGING) {
-            int frameCount = 0;
-            ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_FRAME_COUNT,
-                                                &frameCount, 1));
-        }
-    }
-
-    if (CAMERA_BURST_DEBUGGING) {
-        previewRequest.dump(STDOUT_FILENO);
-    }
-
-    // Submit capture requests
-    for (int i = 0; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        CameraMetadata tmpRequest = previewRequest;
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_EXPOSURE_TIME,
-                                        &exposures[i], 1));
-        ALOGV("Submitting capture request %d with exposure %" PRId64, i,
-            exposures[i]);
-        dout << "Capture request " << i << " exposure is "
-             << (exposures[i]/1e6f) << std::endl;
-        ASSERT_EQ(OK, mDevice->capture(tmpRequest));
-    }
-
-    dout << "Buffer dimensions " << mWidth << "x" << mHeight << std::endl;
-
-    float brightnesses[CAMERA_FRAME_BURST_COUNT];
-    // Get each frame (metadata) and then the buffer. Calculate brightness.
-    for (int i = 0; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        ALOGV("Reading capture request %d with exposure %" PRId64, i, exposures[i]);
-        ASSERT_EQ(OK, mDevice->waitForNextFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("Reading capture request-1 %d", i);
-        CaptureResult result;
-        ASSERT_EQ(OK, mDevice->getNextResult(&result));
-        ALOGV("Reading capture request-2 %d", i);
-
-        ASSERT_EQ(OK, mFrameListener->waitForFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("We got the frame now");
-
-        CpuConsumer::LockedBuffer imgBuffer;
-        ASSERT_EQ(OK, mCpuConsumer->lockNextBuffer(&imgBuffer));
-
-        int underexposed, overexposed;
-        long long brightness = TotalBrightness(imgBuffer, &underexposed,
-                                               &overexposed);
-        float avgBrightness = brightness * 1.0f /
-                              (mWidth * mHeight - (underexposed + overexposed));
-        ALOGV("Total brightness for frame %d was %lld (underexposed %d, "
-              "overexposed %d), avg %f", i, brightness, underexposed,
-              overexposed, avgBrightness);
-        dout << "Average brightness (frame " << i << ") was " << avgBrightness
-             << " (underexposed " << underexposed << ", overexposed "
-             << overexposed << ")" << std::endl;
-
-        ASSERT_EQ(OK, mCpuConsumer->unlockBuffer(imgBuffer));
-
-        brightnesses[i] = avgBrightness;
-    }
-
-    // Calculate max consecutive frame exposure doubling
-    float prev = brightnesses[0];
-    int doubling_count = 1;
-    int max_doubling_count = 0;
-    for (int i = 1; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        if (fabs(brightnesses[i] - prev*CAMERA_EXPOSURE_DOUBLE)
-            <= CAMERA_EXPOSURE_DOUBLING_THRESHOLD) {
-            doubling_count++;
-        }
-        else {
-            max_doubling_count = std::max(max_doubling_count, doubling_count);
-            doubling_count = 1;
-        }
-        prev = brightnesses[i];
-    }
-
-    dout << "max doubling count: " << max_doubling_count << std::endl;
-
-    /**
-     * Make this check warning only, since the brightness calculation is not reliable
-     * and we have separate test to cover this case. Plus it is pretty subtle to make
-     * it right without complicating the test too much.
-     */
-    WARN_LE(CAMERA_EXPOSURE_DOUBLING_COUNT, max_doubling_count)
-            << "average brightness should double at least "
-            << CAMERA_EXPOSURE_DOUBLING_COUNT
-            << " times over each consecutive frame as the exposure is doubled"
-            << std::endl;
-}
-
-/**
- * This test varies exposure time, frame duration, and sensitivity for a
- * burst of captures. It picks values by default, but the selection can be
- * overridden with the environment variables
- *   CAMERA2_TEST_VARIABLE_BURST_EXPOSURE_TIMES
- *   CAMERA2_TEST_VARIABLE_BURST_FRAME_DURATIONS
- *   CAMERA2_TEST_VARIABLE_BURST_SENSITIVITIES
- * which must all be a list of comma-separated values, and each list must be
- * the same length.  In addition, if the environment variable
- *   CAMERA2_TEST_VARIABLE_BURST_DUMP_FRAMES
- * is set to 1, then the YUV buffers are dumped into files named
- *   "camera2_test_variable_burst_frame_NNN.yuv"
- *
- * For example:
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_EXPOSURE_TIMES 10000000,20000000
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_FRAME_DURATIONS 40000000,40000000
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_SENSITIVITIES 200,100
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_DUMP_FRAMES 1
- *   $ /data/nativetest/camera2_test/camera2_test --gtest_filter="*VariableBurst"
- */
-TEST_F(CameraBurstTest, VariableBurst) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    // Bounds for checking frame duration is within range
-    const nsecs_t DURATION_UPPER_BOUND = 10 * MSEC;
-    const nsecs_t DURATION_LOWER_BOUND = 20 * MSEC;
-
-    // Threshold for considering two captures to have equivalent exposure value,
-    // as a ratio of the smaller EV to the larger EV.
-    const float   EV_MATCH_BOUND = 0.95;
-    // Bound for two captures with equivalent exp values to have the same
-    // measured brightness, in 0-255 luminance.
-    const float   BRIGHTNESS_MATCH_BOUND = 5;
-
-    // Environment variables to look for to override test settings
-    const char *expEnv         = "CAMERA2_TEST_VARIABLE_BURST_EXPOSURE_TIMES";
-    const char *durationEnv    = "CAMERA2_TEST_VARIABLE_BURST_FRAME_DURATIONS";
-    const char *sensitivityEnv = "CAMERA2_TEST_VARIABLE_BURST_SENSITIVITIES";
-    const char *dumpFrameEnv   = "CAMERA2_TEST_VARIABLE_BURST_DUMP_FRAMES";
-
-    // Range of valid exposure times, in nanoseconds
-    int64_t minExp = 0, maxExp = 0;
-    // List of valid sensor sensitivities
-    Vector<int32_t> sensitivities;
-    // Range of valid frame durations, in nanoseconds
-    int64_t minDuration = 0, maxDuration = 0;
-
-    {
-        camera_metadata_ro_entry exposureTimeRange =
-            GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
-
-        EXPECT_EQ(2u, exposureTimeRange.count) << "Bad exposure time range tag."
-                "Using default values";
-        if (exposureTimeRange.count == 2) {
-            minExp = exposureTimeRange.data.i64[0];
-            maxExp = exposureTimeRange.data.i64[1];
-        }
-
-        EXPECT_LT(0, minExp) << "Minimum exposure time is 0";
-        EXPECT_LT(0, maxExp) << "Maximum exposure time is 0";
-        EXPECT_LE(minExp, maxExp) << "Minimum exposure is greater than maximum";
-
-        if (minExp == 0) {
-            minExp = 1 * MSEC; // Fallback minimum exposure time
-        }
-
-        if (maxExp == 0) {
-            maxExp = 10 * SEC; // Fallback maximum exposure time
-        }
-    }
-
-    camera_metadata_ro_entry hardwareLevel =
-        GetStaticEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
-    ASSERT_EQ(1u, hardwareLevel.count);
-    uint8_t level = hardwareLevel.data.u8[0];
-    ASSERT_GE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
-    ASSERT_LE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
-    if (level == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) {
-        const ::testing::TestInfo* const test_info =
-            ::testing::UnitTest::GetInstance()->current_test_info();
-        std::cerr << "Skipping test "
-                  << test_info->test_case_name() << "."
-                  << test_info->name()
-                  << " because HAL hardware supported level is limited "
-                  << std::endl;
-        return;
-    }
-
-    dout << "Stream size is " << mWidth << " x " << mHeight << std::endl;
-    dout << "Valid exposure range is: " <<
-            minExp << " - " << maxExp << " ns " << std::endl;
-
-    {
-        camera_metadata_ro_entry sensivityRange =
-            GetStaticEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
-        EXPECT_EQ(2u, sensivityRange.count) << "No sensitivity range listed."
-                "Falling back to default set.";
-        int32_t minSensitivity = 100;
-        int32_t maxSensitivity = 800;
-        if (sensivityRange.count == 2) {
-            ASSERT_GT(sensivityRange.data.i32[0], 0);
-            ASSERT_GT(sensivityRange.data.i32[1], 0);
-            minSensitivity = sensivityRange.data.i32[0];
-            maxSensitivity = sensivityRange.data.i32[1];
-        }
-        int32_t count = (maxSensitivity - minSensitivity + 99) / 100;
-        sensitivities.push_back(minSensitivity);
-        for (int i = 1; i < count; i++) {
-            sensitivities.push_back(minSensitivity + i * 100);
-        }
-        sensitivities.push_back(maxSensitivity);
-    }
-
-    dout << "Available sensitivities: ";
-    for (size_t i = 0; i < sensitivities.size(); i++) {
-        dout << sensitivities[i] << " ";
-    }
-    dout << std::endl;
-
-    {
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_ro_entry availableProcessedSizes =
-                    GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-
-            camera_metadata_ro_entry availableProcessedMinFrameDurations =
-                    GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
-
-            EXPECT_EQ(availableProcessedSizes.count,
-                    availableProcessedMinFrameDurations.count * 2) <<
-                    "The number of minimum frame durations doesn't match the number of "
-                    "available sizes. Using fallback values";
-
-            if (availableProcessedSizes.count ==
-                    availableProcessedMinFrameDurations.count * 2) {
-                bool gotSize = false;
-                for (size_t i = 0; i < availableProcessedSizes.count; i += 2) {
-                    if (availableProcessedSizes.data.i32[i] == mWidth &&
-                            availableProcessedSizes.data.i32[i+1] == mHeight) {
-                        gotSize = true;
-                        minDuration = availableProcessedMinFrameDurations.data.i64[i/2];
-                    }
-                }
-                EXPECT_TRUE(gotSize) << "Can't find stream size in list of "
-                        "available sizes: " << mWidth << ", " << mHeight;
-            }
-            if (minDuration == 0) {
-                minDuration = 1 * SEC / 30; // Fall back to 30 fps as minimum duration
-            }
-        } else {
-            minDuration = getMinFrameDurationFor(
-                    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, mWidth, mHeight);
-        }
-        ASSERT_LT(0, minDuration);
-
-        camera_metadata_ro_entry maxFrameDuration =
-                GetStaticEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION);
-
-        EXPECT_EQ(1u, maxFrameDuration.count) << "No valid maximum frame duration";
-
-        if (maxFrameDuration.count == 1) {
-            maxDuration = maxFrameDuration.data.i64[0];
-        }
-
-        EXPECT_GT(maxDuration, 0) << "Max duration is 0 or not given, using fallback";
-
-        if (maxDuration == 0) {
-            maxDuration = 10 * SEC; // Fall back to 10 seconds as max duration
-        }
-
-    }
-    dout << "Available frame duration range for configured stream size: "
-         << minDuration << " - " << maxDuration << " ns" << std::endl;
-
-    // Get environment variables if set
-    const char *expVal = getenv(expEnv);
-    const char *durationVal = getenv(durationEnv);
-    const char *sensitivityVal = getenv(sensitivityEnv);
-
-    bool gotExp = (expVal != NULL);
-    bool gotDuration = (durationVal != NULL);
-    bool gotSensitivity = (sensitivityVal != NULL);
-
-    // All or none must be provided if using override envs
-    ASSERT_TRUE( (gotDuration && gotExp && gotSensitivity) ||
-            (!gotDuration && !gotExp && !gotSensitivity) ) <<
-            "Incomplete set of environment variable overrides provided";
-
-    Vector<int64_t> expList, durationList;
-    Vector<int32_t> sensitivityList;
-    if (gotExp) {
-        ParseList(expVal, expList);
-        ParseList(durationVal, durationList);
-        ParseList(sensitivityVal, sensitivityList);
-
-        ASSERT_TRUE(
-            (expList.size() == durationList.size()) &&
-            (durationList.size() == sensitivityList.size())) <<
-                "Mismatched sizes in env lists, or parse error";
-
-        dout << "Using burst list from environment with " << expList.size() <<
-                " captures" << std::endl;
-    } else {
-        // Create a default set of controls based on the available ranges
-
-        int64_t e;
-        int64_t d;
-        int32_t s;
-
-        // Exposure ramp
-
-        e = minExp;
-        d = minDuration;
-        s = sensitivities[0];
-        while (e < maxExp) {
-            expList.push_back(e);
-            durationList.push_back(d);
-            sensitivityList.push_back(s);
-            e = e * 2;
-        }
-        e = maxExp;
-        expList.push_back(e);
-        durationList.push_back(d);
-        sensitivityList.push_back(s);
-
-        // Duration ramp
-
-        e = 30 * MSEC;
-        d = minDuration;
-        s = sensitivities[0];
-        while (d < maxDuration) {
-            // make sure exposure <= frame duration
-            expList.push_back(e > d ? d : e);
-            durationList.push_back(d);
-            sensitivityList.push_back(s);
-            d = d * 2;
-        }
-
-        // Sensitivity ramp
-
-        e = 30 * MSEC;
-        d = 30 * MSEC;
-        d = d > minDuration ? d : minDuration;
-        for (size_t i = 0; i < sensitivities.size(); i++) {
-            expList.push_back(e);
-            durationList.push_back(d);
-            sensitivityList.push_back(sensitivities[i]);
-        }
-
-        // Constant-EV ramp, duration == exposure
-
-        e = 30 * MSEC; // at ISO 100
-        for (size_t i = 0; i < sensitivities.size(); i++) {
-            int64_t e_adj = e * 100 / sensitivities[i];
-            expList.push_back(e_adj);
-            durationList.push_back(e_adj > minDuration ? e_adj : minDuration);
-            sensitivityList.push_back(sensitivities[i]);
-        }
-
-        dout << "Default burst sequence created with " << expList.size() <<
-                " entries" << std::endl;
-    }
-
-    // Validate the list, but warn only
-    for (size_t i = 0; i < expList.size(); i++) {
-        EXPECT_GE(maxExp, expList[i])
-                << "Capture " << i << " exposure too long: " << expList[i];
-        EXPECT_LE(minExp, expList[i])
-                << "Capture " << i << " exposure too short: " << expList[i];
-        EXPECT_GE(maxDuration, durationList[i])
-                << "Capture " << i << " duration too long: " << durationList[i];
-        EXPECT_LE(minDuration, durationList[i])
-                 << "Capture " << i << " duration too short: "  << durationList[i];
-        bool validSensitivity = false;
-        for (size_t j = 0; j < sensitivities.size(); j++) {
-            if (sensitivityList[i] == sensitivities[j]) {
-                validSensitivity = true;
-                break;
-            }
-        }
-        EXPECT_TRUE(validSensitivity)
-                << "Capture " << i << " sensitivity not in list: " << sensitivityList[i];
-    }
-
-    // Check if debug yuv dumps are requested
-
-    bool dumpFrames = false;
-    {
-        const char *frameDumpVal = getenv(dumpFrameEnv);
-        if (frameDumpVal != NULL) {
-            if (frameDumpVal[0] == '1') dumpFrames = true;
-        }
-    }
-
-    dout << "Dumping YUV frames " <<
-            (dumpFrames ? "enabled, not checking timing" : "disabled") << std::endl;
-
-    // Create a base preview request, turning off all 3A
-    CameraMetadata previewRequest;
-    ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                                                &previewRequest));
-    {
-        Vector<int32_t> outputStreamIds;
-        outputStreamIds.push(mStreamId);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                                            outputStreamIds));
-
-        // Disable all 3A routines
-        uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_CONTROL_MODE,
-                                            &cmOff, 1));
-
-        int requestId = 1;
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
-                                            &requestId, 1));
-    }
-
-    // Submit capture requests
-
-    for (size_t i = 0; i < expList.size(); ++i) {
-        CameraMetadata tmpRequest = previewRequest;
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_EXPOSURE_TIME,
-                                        &expList[i], 1));
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_FRAME_DURATION,
-                                        &durationList[i], 1));
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_SENSITIVITY,
-                                        &sensitivityList[i], 1));
-        ALOGV("Submitting capture %zu with exposure %" PRId64 ", frame duration %" PRId64 ", sensitivity %d",
-                i, expList[i], durationList[i], sensitivityList[i]);
-        dout << "Capture request " << i <<
-                ": exposure is " << (expList[i]/1e6f) << " ms" <<
-                ", frame duration is " << (durationList[i]/1e6f) << " ms" <<
-                ", sensitivity is " << sensitivityList[i] <<
-                std::endl;
-        ASSERT_EQ(OK, mDevice->capture(tmpRequest));
-    }
-
-    Vector<float> brightnesses;
-    Vector<nsecs_t> captureTimes;
-    brightnesses.setCapacity(expList.size());
-    captureTimes.setCapacity(expList.size());
-
-    // Get each frame (metadata) and then the buffer. Calculate brightness.
-    for (size_t i = 0; i < expList.size(); ++i) {
-
-        ALOGV("Reading request %zu", i);
-        dout << "Waiting for capture " << i << ": " <<
-                " exposure " << (expList[i]/1e6f) << " ms," <<
-                " frame duration " << (durationList[i]/1e6f) << " ms," <<
-                " sensitivity " << sensitivityList[i] <<
-                std::endl;
-
-        // Set wait limit based on expected frame duration, or minimum timeout
-        int64_t waitLimit = CAMERA_FRAME_TIMEOUT;
-        if (expList[i] * 2 > waitLimit) waitLimit = expList[i] * 2;
-        if (durationList[i] * 2 > waitLimit) waitLimit = durationList[i] * 2;
-
-        ASSERT_EQ(OK, mDevice->waitForNextFrame(waitLimit));
-        ALOGV("Reading capture request-1 %zu", i);
-        CaptureResult result;
-        ASSERT_EQ(OK, mDevice->getNextResult(&result));
-        ALOGV("Reading capture request-2 %zu", i);
-
-        ASSERT_EQ(OK, mFrameListener->waitForFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("We got the frame now");
-
-        captureTimes.push_back(systemTime());
-
-        CpuConsumer::LockedBuffer imgBuffer;
-        ASSERT_EQ(OK, mCpuConsumer->lockNextBuffer(&imgBuffer));
-
-        int underexposed, overexposed;
-        float avgBrightness = 0;
-        long long brightness = TotalBrightness(imgBuffer, &underexposed,
-                                               &overexposed);
-        int numValidPixels = mWidth * mHeight - (underexposed + overexposed);
-        if (numValidPixels != 0) {
-            avgBrightness = brightness * 1.0f / numValidPixels;
-        } else if (underexposed < overexposed) {
-            avgBrightness = 255;
-        }
-
-        ALOGV("Total brightness for frame %zu was %lld (underexposed %d, "
-              "overexposed %d), avg %f", i, brightness, underexposed,
-              overexposed, avgBrightness);
-        dout << "Average brightness (frame " << i << ") was " << avgBrightness
-             << " (underexposed " << underexposed << ", overexposed "
-             << overexposed << ")" << std::endl;
-        brightnesses.push_back(avgBrightness);
-
-        if (i != 0) {
-            float prevEv = static_cast<float>(expList[i - 1]) * sensitivityList[i - 1];
-            float currentEv = static_cast<float>(expList[i]) * sensitivityList[i];
-            float evRatio = (prevEv > currentEv) ? (currentEv / prevEv) :
-                    (prevEv / currentEv);
-            if ( evRatio > EV_MATCH_BOUND ) {
-                WARN_LT(fabs(brightnesses[i] - brightnesses[i - 1]),
-                        BRIGHTNESS_MATCH_BOUND) <<
-                        "Capture brightness different from previous, even though "
-                        "they have the same EV value. Ev now: " << currentEv <<
-                        ", previous: " << prevEv << ". Brightness now: " <<
-                        brightnesses[i] << ", previous: " << brightnesses[i-1] <<
-                        std::endl;
-            }
-            // Only check timing if not saving to disk, since that slows things
-            // down substantially
-            if (!dumpFrames) {
-                nsecs_t timeDelta = captureTimes[i] - captureTimes[i-1];
-                nsecs_t expectedDelta = expList[i] > durationList[i] ?
-                        expList[i] : durationList[i];
-                WARN_LT(timeDelta, expectedDelta + DURATION_UPPER_BOUND) <<
-                        "Capture took " << timeDelta << " ns to receive, but expected"
-                        " frame duration was " << expectedDelta << " ns." <<
-                        std::endl;
-                WARN_GT(timeDelta, expectedDelta - DURATION_LOWER_BOUND) <<
-                        "Capture took " << timeDelta << " ns to receive, but expected"
-                        " frame duration was " << expectedDelta << " ns." <<
-                        std::endl;
-                dout << "Time delta from previous frame: " << timeDelta / 1e6 <<
-                        " ms.  Expected " << expectedDelta / 1e6 << " ms" << std::endl;
-            }
-        }
-
-        if (dumpFrames) {
-            String8 dumpName =
-                    String8::format("/data/local/tmp/camera2_test_variable_burst_frame_%03zu.yuv", i);
-            dout << "  Writing YUV dump to " << dumpName << std::endl;
-            DumpYuvToFile(dumpName, imgBuffer);
-        }
-
-        ASSERT_EQ(OK, mCpuConsumer->unlockBuffer(imgBuffer));
-    }
-
-}
-
-}
-}
-}
diff --git a/tests/camera2/CameraFrameTests.cpp b/tests/camera2/CameraFrameTests.cpp
deleted file mode 100644
index 3c5abf7..0000000
--- a/tests/camera2/CameraFrameTests.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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.
- */
-
-#include <gtest/gtest.h>
-
-#define LOG_TAG "CameraFrameTest"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include <common/CameraDeviceBase.h>
-#include <utils/StrongPointer.h>
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-
-#include <unistd.h>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-#define CAMERA_FRAME_TIMEOUT    1000000000 //nsecs (1 secs)
-#define CAMERA_HEAP_COUNT       2 //HALBUG: 1 means registerBuffers fails
-#define CAMERA_FRAME_DEBUGGING  0
-
-using namespace android;
-using namespace android::camera2;
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-static CameraStreamParams STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_STREAM_AUTO_CPU_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-class CameraFrameTest
-    : public ::testing::TestWithParam<int>,
-      public CameraStreamFixture {
-
-public:
-    CameraFrameTest() : CameraStreamFixture(STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        if (!HasFatalFailure()) {
-            CreateStream();
-        }
-    }
-
-    ~CameraFrameTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-
-        if (mDevice.get()) {
-            mDevice->waitUntilDrained();
-        }
-    }
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-
-protected:
-
-};
-
-TEST_P(CameraFrameTest, GetFrame) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    /* Submit a PREVIEW type request, then wait until we get the frame back */
-    CameraMetadata previewRequest;
-    ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                                                &previewRequest));
-    {
-        Vector<int32_t> outputStreamIds;
-        outputStreamIds.push(mStreamId);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                                            outputStreamIds));
-        if (CAMERA_FRAME_DEBUGGING) {
-            int frameCount = 0;
-            ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_FRAME_COUNT,
-                                                &frameCount, 1));
-        }
-    }
-
-    if (CAMERA_FRAME_DEBUGGING) {
-        previewRequest.dump(STDOUT_FILENO);
-    }
-
-    for (int i = 0; i < GetParam(); ++i) {
-        ALOGV("Submitting capture request %d", i);
-        CameraMetadata tmpRequest = previewRequest;
-        ASSERT_EQ(OK, mDevice->capture(tmpRequest));
-    }
-
-    for (int i = 0; i < GetParam(); ++i) {
-        ALOGV("Reading capture request %d", i);
-        ASSERT_EQ(OK, mDevice->waitForNextFrame(CAMERA_FRAME_TIMEOUT));
-
-        CaptureResult result;
-        ASSERT_EQ(OK, mDevice->getNextResult(&result));
-
-        // wait for buffer to be available
-        ASSERT_EQ(OK, mFrameListener->waitForFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("We got the frame now");
-
-        // mark buffer consumed so producer can re-dequeue it
-        CpuConsumer::LockedBuffer imgBuffer;
-        ASSERT_EQ(OK, mCpuConsumer->lockNextBuffer(&imgBuffer));
-        ASSERT_EQ(OK, mCpuConsumer->unlockBuffer(imgBuffer));
-    }
-
-}
-
-//FIXME: dont hardcode stream params, and also test multistream
-INSTANTIATE_TEST_CASE_P(FrameParameterCombinations, CameraFrameTest,
-    testing::Range(1, 10));
-
-
-}
-}
-}
diff --git a/tests/camera2/CameraMetadataTests.cpp b/tests/camera2/CameraMetadataTests.cpp
deleted file mode 100644
index 16b2dd9..0000000
--- a/tests/camera2/CameraMetadataTests.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_NDEBUG 0
-#define LOG_TAG "CameraMetadataTestFunctional"
-
-#include <stdint.h>
-
-#include <string>
-
-#include "cutils/properties.h"
-#include "log/log.h"
-#include "utils/Errors.h"
-
-#include "gtest/gtest.h"
-#include "system/camera_metadata.h"
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include "common/CameraDeviceBase.h"
-#include "utils/StrongPointer.h"
-
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-//FIXME: dont hardcode
-static CameraStreamParams METADATA_STREAM_PARAMETERS = {
-    /*mFormat*/     HAL_PIXEL_FORMAT_YCrCb_420_SP,
-    /*mHeapCount*/  2
-};
-
-class CameraMetadataTest
-    : public ::testing::Test,
-      public CameraStreamFixture {
-
-public:
-    CameraMetadataTest()
-    : CameraStreamFixture(METADATA_STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-    }
-
-    ~CameraMetadataTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    int GetTypeFromTag(uint32_t tag) const {
-        return get_camera_metadata_tag_type(tag);
-    }
-
-    int GetTypeFromStaticTag(uint32_t tag) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        return entry.type;
-    }
-
-    int GetEntryCountFromStaticTag(uint32_t tag) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        return entry.count;
-    }
-
-    bool HasElementInArrayFromStaticTag(uint32_t tag, int32_t element) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        for (size_t i = 0; i < entry.count; ++i) {
-            if (entry.data.i32[i] == element)
-                return true;
-        }
-        return false;
-    }
-
-protected:
-
-};
-
-TEST_F(CameraMetadataTest, types) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    //FIXME: set this up in an external file of some sort (xml?)
-    {
-        char value[PROPERTY_VALUE_MAX];
-        property_get("ro.build.id", value, "");
-        std::string str_value(value);
-
-        if (str_value == "manta")
-        {
-            EXPECT_EQ(TYPE_BYTE,
-                GetTypeFromStaticTag(ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO));
-            EXPECT_EQ(TYPE_BYTE,
-                GetTypeFromStaticTag(ANDROID_QUIRKS_USE_ZSL_FORMAT));
-            EXPECT_EQ(TYPE_BYTE,
-                GetTypeFromStaticTag(ANDROID_QUIRKS_METERING_CROP_REGION));
-        }
-    }
-
-    /*
-    TODO:
-    go through all static metadata and make sure all fields we expect
-    that are there, ARE there.
-
-    dont worry about the type as its enforced by the metadata api
-    we can probably check the range validity though
-    */
-
-    if (0) {
-        camera_metadata_ro_entry entry;
-        EXPECT_EQ(TYPE_BYTE,     entry.type);
-        EXPECT_EQ(TYPE_INT32,    entry.type);
-        EXPECT_EQ(TYPE_FLOAT,    entry.type);
-        EXPECT_EQ(TYPE_INT64,    entry.type);
-        EXPECT_EQ(TYPE_DOUBLE,   entry.type);
-        EXPECT_EQ(TYPE_RATIONAL, entry.type);
-    }
-}
-
-TEST_F(CameraMetadataTest, RequiredFormats) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    EXPECT_TRUE(
-        HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                                       HAL_PIXEL_FORMAT_BLOB)); // JPEG
-
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_0) {
-        // HAL2 can support either flexible YUV or YV12 + NV21
-        if (!HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YCbCr_420_888)) {
-
-            EXPECT_TRUE(
-                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YCrCb_420_SP)); // NV21
-
-            EXPECT_TRUE(
-                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YV12));
-        }
-    } else {
-        // HAL3 must support flexible YUV
-        EXPECT_TRUE(HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YCbCr_420_888));
-    }
-
-}
-
-TEST_F(CameraMetadataTest, SaneResolutions) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-        // Iff there are listed raw resolutions, the format should be available
-        int rawResolutionsCount =
-                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_RAW_SIZES);
-        if (rawResolutionsCount > 0) {
-            EXPECT_TRUE(
-                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_RAW16));
-        }
-
-        // Required processed sizes.
-        int processedSizeCount =
-               GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        EXPECT_NE(0, processedSizeCount);
-        EXPECT_EQ(0, processedSizeCount % 2); // multiple of 2 (w,h)
-
-        // Required JPEG sizes
-        int jpegSizeCount =
-                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
-        EXPECT_NE(0, jpegSizeCount);
-        EXPECT_EQ(0, jpegSizeCount % 2); // multiple of 2 (w,h)
-    } else {
-        int strmConfigCount =
-                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
-        EXPECT_NE(0, strmConfigCount);
-        EXPECT_EQ(0, strmConfigCount % 4); // multiple of 4 (format,w,h,output?)
-    }
-
-}
-
-}
-}
-}
diff --git a/tests/camera2/CameraModuleFixture.h b/tests/camera2/CameraModuleFixture.h
deleted file mode 100644
index 25513af..0000000
--- a/tests/camera2/CameraModuleFixture.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __ANDROID_HAL_CAMERA2_TESTS_MODULE_FIXTURE__
-#define __ANDROID_HAL_CAMERA2_TESTS_MODULE_FIXTURE__
-
-#include <gtest/gtest.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include <common/CameraModule.h>
-#include <device3/Camera3Device.h>
-
-#include "camera2_utils.h"
-#include "TestExtensions.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-template <bool InfoQuirk = false>
-struct CameraModuleFixture {
-
-    explicit CameraModuleFixture(int CameraID = -1) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        mCameraID = CameraID;
-    }
-
-    ~CameraModuleFixture() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    camera_metadata_ro_entry GetStaticEntry(uint32_t tag) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        return entry;
-    }
-
-    void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-
-        camera_module_t *rawModule;
-        ASSERT_LE(0, hw_get_module(CAMERA_HARDWARE_MODULE_ID,
-            (const hw_module_t **)&rawModule)) << "Could not load camera module";
-        ASSERT_NE((void*)0, rawModule);
-        mModule = new CameraModule(rawModule);
-
-        mNumberOfCameras = mModule->getNumberOfCameras();
-        ASSERT_LE(0, mNumberOfCameras);
-
-        ASSERT_LE(
-            CAMERA_MODULE_API_VERSION_2_0, mModule->getModuleApiVersion())
-            << "Wrong module API version";
-
-        /* For using this fixture in other tests only */
-        SetUpMixin();
-    }
-
-    void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-
-        delete mModule;
-        TearDownMixin();
-
-        /* important: device must be destructed before closing module,
-           since it calls back into HAL */
-        mDevice.clear();
-
-        if (!TEST_EXTENSION_FORKING_ENABLED) {
-            ASSERT_EQ(0, HWModuleHelpers::closeModule(mModule->getDso()))
-                << "Failed to close camera HAL module";
-        }
-    }
-
-    void CreateCamera(int cameraID, /*out*/ sp<CameraDeviceBase> *device) {
-        struct camera_info info;
-        ASSERT_EQ(OK, mModule->getCameraInfo(cameraID, &info));
-
-        ASSERT_GE((int)info.device_version, CAMERA_DEVICE_API_VERSION_3_0) <<
-                "Device version too old for camera " << cameraID << ". Version: " <<
-                info.device_version;
-        switch(info.device_version) {
-            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);
-                break;
-            default:
-                device->clear();
-                FAIL() << "Device version unknown for camera " << cameraID << ". Version: " <<
-                       info.device_version;
-        }
-
-    }
-
-    int getDeviceVersion() {
-        return getDeviceVersion(mCameraID);
-    }
-
-    int getDeviceVersion(int cameraId, status_t* status = NULL) {
-        camera_info info;
-        status_t res;
-        res = mModule->getCameraInfo(cameraId, &info);
-        if (status != NULL) *status = res;
-
-        return info.device_version;
-    }
-
-private:
-
-    void SetUpMixin() {
-        /* For using this fixture in other tests only */
-        if (mCameraID != -1) {
-            EXPECT_LE(0, mCameraID);
-            EXPECT_LT(mCameraID, mNumberOfCameras);
-
-            /* HALBUG (Exynos5); crashes if we skip calling get_camera_info
-               before initializing. Need info anyway now. */
-
-            CreateCamera(mCameraID, &mDevice);
-
-            ASSERT_TRUE(mDevice != NULL) << "Failed to open device " << mCameraID;
-            ASSERT_EQ(OK, mDevice->initialize(mModule))
-                << "Failed to initialize device " << mCameraID;
-        }
-    }
-
-    void TearDownMixin() {
-
-    }
-
-protected:
-    int mNumberOfCameras;
-    CameraModule *mModule;
-    sp<CameraDeviceBase> mDevice;
-
-private:
-    int mCameraID;
-};
-
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/CameraModuleTests.cpp b/tests/camera2/CameraModuleTests.cpp
deleted file mode 100644
index 2b6c757..0000000
--- a/tests/camera2/CameraModuleTests.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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.
- */
-
-#include <gtest/gtest.h>
-
-#define LOG_TAG "CameraModuleTest"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/StrongPointer.h>
-#include <common/CameraDeviceBase.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include "CameraModuleFixture.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-class CameraModuleTest : public ::testing::Test,
-                                  public CameraModuleFixture<> {
-
-public:
-    CameraModuleTest() {
-        CameraModuleFixture::SetUp();
-    }
-
-    ~CameraModuleTest() {
-        CameraModuleFixture::TearDown();
-    }
-
-    status_t initializeDevice(int cameraId) {
-
-        // ignore HAL1s. count as test pass
-        status_t stat;
-        if (isDeviceVersionHal2(cameraId, &stat) && stat == OK) {
-            stat = mDevice->initialize(mModule);
-        }
-
-        return stat;
-    }
-
-    bool isDeviceVersionHal2(int cameraId, status_t* status) {
-        return getDeviceVersion(cameraId, status)
-               >= CAMERA_DEVICE_API_VERSION_2_0;
-    }
-};
-
-TEST_F(CameraModuleTest, LoadModule) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    status_t stat;
-    for (int i = 0; i < mNumberOfCameras; ++i) {
-        if (isDeviceVersionHal2(i, &stat) && stat == OK) {
-            CreateCamera(i, &mDevice);
-            ASSERT_EQ(OK, initializeDevice(i))
-                << "Failed to initialize device " << i;
-            mDevice.clear();
-        } else {
-            const ::testing::TestInfo* const test_info =
-                ::testing::UnitTest::GetInstance()->current_test_info();
-            std::cerr << "Skipping test "
-                      << test_info->test_case_name() << "."
-                      << test_info->name()
-                      << " because HAL device version is V1"
-                      << std::endl;
-        }
-    }
-
-}
-
-TEST_F(CameraModuleTest, LoadModuleBadIndices) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    int idx[] = { -1, mNumberOfCameras, mNumberOfCameras + 1 };
-    hw_device_t *device = NULL;
-
-    for (unsigned i = 0; i < sizeof(idx)/sizeof(idx[0]); ++i) {
-        String8 deviceName = String8::format("%d", idx[i]);
-        status_t res = mModule->open(deviceName, &device);
-        EXPECT_NE(OK, res);
-        EXPECT_EQ(-ENODEV, res)
-            << "Incorrect error code when trying to open camera with invalid id "
-            << deviceName;
-    }
-}
-
-TEST_F(CameraModuleTest, GetCameraInfo) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    for (int i = 0; i < mNumberOfCameras; ++i) {
-        struct camera_info info;
-        ASSERT_EQ(OK, mModule->getCameraInfo(i, &info));
-    }
-
-}
-
-TEST_F(CameraModuleTest, GetCameraInfoBadIndices) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    int idx[] = { -1, mNumberOfCameras, mNumberOfCameras + 1 };
-    for (unsigned i = 0; i < sizeof(idx)/sizeof(idx[0]); ++i) {
-        struct camera_info info;
-        EXPECT_NE(OK, mModule->getCameraInfo(idx[i], &info));
-        EXPECT_EQ(-EINVAL, mModule->getCameraInfo(idx[i], &info))
-            << "Incorrect error code for get_camera_info idx= "
-            << idx[i];
-    }
-}
-
-/**
- * TODO: Additional test to add: open two cameras at once.
- *       (is allowed to fail, at least for now, but should not blow up)
- *     - open same device multiple times
- *     - close same device multiple times
- */
-
-
-
-
-}
-}
-}
diff --git a/tests/camera2/CameraMultiStreamTests.cpp b/tests/camera2/CameraMultiStreamTests.cpp
deleted file mode 100644
index f4aeab7..0000000
--- a/tests/camera2/CameraMultiStreamTests.cpp
+++ /dev/null
@@ -1,713 +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.
- */
-
-#include <inttypes.h>
-#define LOG_TAG "CameraMultiStreamTest"
-//#define LOG_NDEBUG 0
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-#include <gtest/gtest.h>
-#include <utils/Log.h>
-#include <utils/StrongPointer.h>
-#include <common/CameraDeviceBase.h>
-#include <hardware/hardware.h>
-#include <hardware/camera2.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/Surface.h>
-
-#define DEFAULT_FRAME_DURATION 33000000LL // 33ms
-#define CAMERA_HEAP_COUNT       1
-#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
-#define CAMERA_DISPLAY_FORMAT HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
-#define CAMERA_MULTI_STREAM_DEBUGGING  0
-#define CAMERA_FRAME_TIMEOUT    1000000000LL // nsecs (1 secs)
-#define PREVIEW_RENDERING_TIME_INTERVAL 200000 // in unit of us, 200ms
-// 1% tolerance margin for exposure sanity check against metadata
-#define TOLERANCE_MARGIN_METADATA 0.01
-// 5% tolerance margin for exposure sanity check against capture times
-#define TOLERANCE_MARGIN_CAPTURE 0.05
-/* constants for display */
-#define DISPLAY_BUFFER_HEIGHT 1024
-#define DISPLAY_BUFFER_WIDTH 1024
-#define DISPLAY_BUFFER_FORMAT PIXEL_FORMAT_RGB_888
-
-// This test intends to test large preview size but less than 1080p.
-#define PREVIEW_WIDTH_CAP   1920
-#define PREVIEW_HEIGHT_CAP  1080
-// This test intends to test small metering burst size that is less than 640x480
-#define METERING_WIDTH_CAP  640
-#define METERING_HEIGHT_CAP 480
-
-#define EXP_WAIT_MULTIPLIER 2
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-static const CameraStreamParams DEFAULT_STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_EXPOSURE_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-static const CameraStreamParams DISPLAY_STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_DISPLAY_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-class CameraMultiStreamTest
-    : public ::testing::Test,
-      public CameraStreamFixture {
-
-public:
-    CameraMultiStreamTest() : CameraStreamFixture(DEFAULT_STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        if (HasFatalFailure()) {
-            return;
-        }
-        /**
-         * Don't create default stream, each test is in charge of creating
-         * its own streams.
-         */
-    }
-
-    ~CameraMultiStreamTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    sp<SurfaceComposerClient> mComposerClient;
-    sp<SurfaceControl> mSurfaceControl;
-
-    void CreateOnScreenSurface(sp<Surface>& surface) {
-        mComposerClient = new SurfaceComposerClient;
-        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
-
-        mSurfaceControl = mComposerClient->createSurface(
-                String8("CameraMultiStreamTest StreamingImage Surface"),
-                DISPLAY_BUFFER_HEIGHT, DISPLAY_BUFFER_WIDTH,
-                DISPLAY_BUFFER_FORMAT, 0);
-
-        ASSERT_NE((void*)NULL, mSurfaceControl.get());
-        ASSERT_TRUE(mSurfaceControl->isValid());
-
-        SurfaceComposerClient::openGlobalTransaction();
-        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
-        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
-        SurfaceComposerClient::closeGlobalTransaction();
-
-        surface = mSurfaceControl->getSurface();
-
-        ASSERT_NE((void*)NULL, surface.get());
-    }
-
-    struct Size {
-        int32_t width;
-        int32_t height;
-    };
-
-    // Select minimal size by number of pixels.
-    void GetMinSize(const int32_t* data, size_t count,
-            Size* min, int32_t* idx) {
-        ASSERT_NE((int32_t*)NULL, data);
-        int32_t minIdx = 0;
-        int32_t minSize = INT_MAX, tempSize;
-        for (size_t i = 0; i < count; i+=2) {
-            tempSize = data[i] * data[i+1];
-            if (minSize > tempSize) {
-                minSize = tempSize;
-                minIdx = i;
-            }
-        }
-        min->width = data[minIdx];
-        min->height = data[minIdx + 1];
-        *idx = minIdx;
-    }
-
-    // Select maximal size by number of pixels.
-    void GetMaxSize(const int32_t* data, size_t count,
-            Size* max, int32_t* idx) {
-        ASSERT_NE((int32_t*)NULL, data);
-        int32_t maxIdx = 0;
-        int32_t maxSize = INT_MIN, tempSize;
-        for (size_t i = 0; i < count; i+=2) {
-            tempSize = data[i] * data[i+1];
-            if (maxSize < tempSize) {
-                maxSize = tempSize;
-                maxIdx = i;
-            }
-        }
-        max->width = data[maxIdx];
-        max->height = data[maxIdx + 1];
-        *idx = maxIdx;
-    }
-
-    // Cap size by number of pixels.
-    Size CapSize(Size cap, Size input) {
-        if (input.width * input.height > cap.width * cap.height) {
-            return cap;
-        }
-        return input;
-    }
-
-    struct CameraStream : public RefBase {
-
-    public:
-        /**
-         * Only initialize the variables here, do the ASSERT check in
-         * SetUp function. To make this stream useful, the SetUp must
-         * be called before using it.
-         */
-        CameraStream(
-                int width,
-                int height,
-                const sp<CameraDeviceBase>& device,
-                CameraStreamParams param, sp<Surface> surface,
-                bool useCpuConsumer)
-            : mDevice(device),
-              mWidth(width),
-              mHeight(height) {
-            mFormat = param.mFormat;
-            if (useCpuConsumer) {
-                sp<IGraphicBufferProducer> producer;
-                sp<IGraphicBufferConsumer> consumer;
-                BufferQueue::createBufferQueue(&producer, &consumer);
-                mCpuConsumer = new CpuConsumer(consumer, param.mHeapCount);
-                mCpuConsumer->setName(String8(
-                        "CameraMultiStreamTest::mCpuConsumer"));
-                mSurface = new Surface(producer);
-            } else {
-                // Render the stream to screen.
-                mCpuConsumer = NULL;
-                mSurface = surface;
-            }
-
-            mFrameListener = new FrameListener();
-            if (mCpuConsumer != 0) {
-                mCpuConsumer->setFrameAvailableListener(mFrameListener);
-            }
-        }
-
-        /**
-         * Finally create camera stream, and do the ASSERT check, since we
-         * can not do it in ctor.
-         */
-        void SetUp() {
-            ASSERT_EQ(OK,
-                mDevice->createStream(mSurface,
-                    mWidth, mHeight, mFormat, HAL_DATASPACE_UNKNOWN,
-                    CAMERA3_STREAM_ROTATION_0, &mStreamId));
-
-            ASSERT_NE(-1, mStreamId);
-        }
-
-        int GetStreamId() { return mStreamId; }
-        sp<CpuConsumer> GetConsumer() { return mCpuConsumer; }
-        sp<FrameListener> GetFrameListener() { return mFrameListener; }
-
-    protected:
-        ~CameraStream() {
-            if (mDevice.get()) {
-                mDevice->waitUntilDrained();
-                mDevice->deleteStream(mStreamId);
-            }
-            // Clear producer before consumer.
-            mSurface.clear();
-            mCpuConsumer.clear();
-        }
-
-    private:
-        sp<FrameListener>       mFrameListener;
-        sp<CpuConsumer>         mCpuConsumer;
-        sp<Surface>             mSurface;
-        sp<CameraDeviceBase>    mDevice;
-        int                     mStreamId;
-        int                     mWidth;
-        int                     mHeight;
-        int                     mFormat;
-    };
-
-    int64_t GetExposureValue(const CameraMetadata& metaData) {
-        camera_metadata_ro_entry_t entry =
-                metaData.find(ANDROID_SENSOR_EXPOSURE_TIME);
-        EXPECT_EQ(1u, entry.count);
-        if (entry.count == 1) {
-            return entry.data.i64[0];
-        }
-        return -1;
-    }
-
-    int32_t GetSensitivity(const CameraMetadata& metaData) {
-        camera_metadata_ro_entry_t entry =
-                metaData.find(ANDROID_SENSOR_SENSITIVITY);
-        EXPECT_EQ(1u, entry.count);
-        if (entry.count == 1) {
-            return entry.data.i32[0];
-        }
-        return -1;
-    }
-
-    int64_t GetFrameDuration(const CameraMetadata& metaData) {
-        camera_metadata_ro_entry_t entry =
-                metaData.find(ANDROID_SENSOR_FRAME_DURATION);
-        EXPECT_EQ(1u, entry.count);
-        if (entry.count == 1) {
-            return entry.data.i64[0];
-        }
-        return -1;
-    }
-
-    void CreateRequests(CameraMetadata& previewRequest,
-            CameraMetadata& meteringRequest,
-            CameraMetadata& captureRequest,
-            int previewStreamId,
-            int meteringStreamId,
-            int captureStreamId) {
-        int32_t requestId = 0;
-        Vector<int32_t> previewStreamIds;
-        previewStreamIds.push(previewStreamId);
-        ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                &previewRequest));
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                previewStreamIds));
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
-                &requestId, 1));
-
-        // Create metering request, manual settings
-        // Manual control: Disable 3A, noise reduction, edge sharping
-        uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-        uint8_t nrOff = static_cast<uint8_t>(ANDROID_NOISE_REDUCTION_MODE_OFF);
-        uint8_t sharpOff = static_cast<uint8_t>(ANDROID_EDGE_MODE_OFF);
-        Vector<int32_t> meteringStreamIds;
-        meteringStreamIds.push(meteringStreamId);
-        ASSERT_EQ(OK, mDevice->createDefaultRequest(
-                CAMERA2_TEMPLATE_PREVIEW,
-                &meteringRequest));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_REQUEST_OUTPUT_STREAMS,
-                meteringStreamIds));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_CONTROL_MODE,
-                &cmOff, 1));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_NOISE_REDUCTION_MODE,
-                &nrOff, 1));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_EDGE_MODE,
-                &sharpOff, 1));
-
-        // Create capture request, manual settings
-        Vector<int32_t> captureStreamIds;
-        captureStreamIds.push(captureStreamId);
-        ASSERT_EQ(OK, mDevice->createDefaultRequest(
-                CAMERA2_TEMPLATE_PREVIEW,
-                &captureRequest));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_REQUEST_OUTPUT_STREAMS,
-                captureStreamIds));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_CONTROL_MODE,
-                &cmOff, 1));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_NOISE_REDUCTION_MODE,
-                &nrOff, 1));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_EDGE_MODE,
-                &sharpOff, 1));
-    }
-
-    sp<CameraStream> CreateStream(
-            int width,
-            int height,
-            const sp<CameraDeviceBase>& device,
-            CameraStreamParams param = DEFAULT_STREAM_PARAMETERS,
-            const sp<Surface>& surface = NULL,
-            bool useCpuConsumer = true) {
-        param.mFormat = MapAutoFormat(param.mFormat);
-        return new CameraStream(width, height, device,
-                param, surface, useCpuConsumer);
-    }
-
-    void CaptureBurst(CameraMetadata& request, size_t requestCount,
-            const Vector<int64_t>& exposures,
-            const Vector<int32_t>& sensitivities,
-            const sp<CameraStream>& stream,
-            int64_t minFrameDuration,
-            int32_t* requestIdStart) {
-        ASSERT_EQ(OK, request.update(ANDROID_SENSOR_FRAME_DURATION,
-                &minFrameDuration, 1));
-        // Submit a series of requests with the specified exposure/gain values.
-        int32_t targetRequestId = *requestIdStart;
-        for (size_t i = 0; i < requestCount; i++) {
-            ASSERT_EQ(OK, request.update(ANDROID_REQUEST_ID, requestIdStart, 1));
-            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposures[i], 1));
-            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_SENSITIVITY, &sensitivities[i], 1));
-            ASSERT_EQ(OK, mDevice->capture(request));
-            ALOGV("Submitting request with: id %d with exposure %" PRId64 ", sensitivity %d",
-                    *requestIdStart, exposures[i], sensitivities[i]);
-            if (CAMERA_MULTI_STREAM_DEBUGGING) {
-                request.dump(STDOUT_FILENO);
-            }
-            (*requestIdStart)++;
-        }
-        // Get capture burst results.
-        Vector<nsecs_t> captureBurstTimes;
-        sp<CpuConsumer> consumer = stream->GetConsumer();
-        sp<FrameListener> listener = stream->GetFrameListener();
-
-        // Set wait limit based on expected frame duration.
-        int64_t waitLimit = CAMERA_FRAME_TIMEOUT;
-        for (size_t i = 0; i < requestCount; i++) {
-            ALOGV("Reading request result %zu", i);
-
-            /**
-             * Raise the timeout to be at least twice as long as the exposure
-             * time. to avoid a false positive when the timeout is too short.
-             */
-            if ((exposures[i] * EXP_WAIT_MULTIPLIER) > waitLimit) {
-                waitLimit = exposures[i] * EXP_WAIT_MULTIPLIER;
-            }
-
-            CaptureResult result;
-            CameraMetadata frameMetadata;
-            int32_t resultRequestId;
-            do {
-                ASSERT_EQ(OK, mDevice->waitForNextFrame(waitLimit));
-                ASSERT_EQ(OK, mDevice->getNextResult(&result));
-                frameMetadata = result.mMetadata;
-
-                camera_metadata_entry_t resultEntry = frameMetadata.find(ANDROID_REQUEST_ID);
-                ASSERT_EQ(1u, resultEntry.count);
-                resultRequestId = resultEntry.data.i32[0];
-                if (CAMERA_MULTI_STREAM_DEBUGGING) {
-                    std::cout << "capture result req id: " << resultRequestId << std::endl;
-                }
-            } while (resultRequestId != targetRequestId);
-            targetRequestId++;
-            ALOGV("Got capture burst result for request %zu", i);
-
-            // Validate capture result
-            if (CAMERA_MULTI_STREAM_DEBUGGING) {
-                frameMetadata.dump(STDOUT_FILENO);
-            }
-
-            // TODO: Need revisit it to figure out an accurate margin.
-            int64_t resultExposure = GetExposureValue(frameMetadata);
-            int32_t resultSensitivity = GetSensitivity(frameMetadata);
-            EXPECT_LE(sensitivities[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultSensitivity);
-            EXPECT_GE(sensitivities[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultSensitivity);
-            EXPECT_LE(exposures[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultExposure);
-            EXPECT_GE(exposures[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultExposure);
-
-            ASSERT_EQ(OK, listener->waitForFrame(waitLimit));
-            captureBurstTimes.push_back(systemTime());
-            CpuConsumer::LockedBuffer imgBuffer;
-            ASSERT_EQ(OK, consumer->lockNextBuffer(&imgBuffer));
-            ALOGV("Got capture buffer for request %zu", i);
-
-            /**
-             * TODO: Validate capture buffer. Current brightness calculation
-             * is too slow, it also doesn't account for saturation effects,
-             * which is quite common since we are going over a significant
-             * range of EVs. we need figure out some reliable way to validate
-             * buffer data.
-             */
-
-            ASSERT_EQ(OK, consumer->unlockBuffer(imgBuffer));
-            if (i > 0) {
-                nsecs_t timeDelta =
-                        captureBurstTimes[i] - captureBurstTimes[i-1];
-                EXPECT_GE(timeDelta * ( 1 + TOLERANCE_MARGIN_CAPTURE), exposures[i]);
-            }
-        }
-    }
-
-    /**
-     * Intentionally shadow default CreateStream function from base class,
-     * because we don't want any test in this class to use the default
-     * stream creation function.
-     */
-    void CreateStream() {
-    }
-};
-
-/**
- * This test adds multiple stream use case test, basically, test 3
- * streams:
- *
- * 1. Preview stream, with large size that is no bigger than 1080p
- * we render this stream to display and vary the exposure time for
- * for certain amount of time for visualization purpose.
- *
- * 2. Metering stream, with small size that is no bigger than VGA size.
- * a burst is issued for different exposure times and analog gains
- * (or analog gain implemented sensitivities) then check if the capture
- * result metadata matches the request.
- *
- * 3. Capture stream, this is basically similar as meterting stream, but
- * has large size, which is the largest supported JPEG capture size.
- *
- * This multiple stream test is to test if HAL supports:
- *
- * 1. Multiple streams like above, HAL should support at least 3 streams
- * concurrently: one preview stream, 2 other YUV stream.
- *
- * 2. Manual control(gain/exposure) of mutiple burst capture.
- */
-// Disable this test for now, as we need cleanup the usage of the deprecated tag quite a bit.
-TEST_F(CameraMultiStreamTest, DISABLED_MultiBurst) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    const int32_t* implDefData;
-    size_t implDefCount;
-    const int32_t* jpegData;
-    size_t jpegCount;
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-        camera_metadata_ro_entry availableProcessedSizes =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        ASSERT_EQ(0u, availableProcessedSizes.count % 2);
-        ASSERT_GE(availableProcessedSizes.count, 2u);
-        camera_metadata_ro_entry availableProcessedMinFrameDurations =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
-        EXPECT_EQ(availableProcessedSizes.count,
-            availableProcessedMinFrameDurations.count * 2);
-
-        camera_metadata_ro_entry availableJpegSizes =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
-        ASSERT_EQ(0u, availableJpegSizes.count % 2);
-        ASSERT_GE(availableJpegSizes.count, 2u);
-        implDefData = availableProcessedSizes.data.i32;
-        implDefCount = availableProcessedSizes.count;
-        jpegData = availableJpegSizes.data.i32;
-        jpegCount = availableJpegSizes.count;
-    } else {
-        getResolutionList(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, &implDefData, &implDefCount);
-        ASSERT_NE(0u, implDefCount)
-            << "Missing implementation defined sizes";
-        ASSERT_EQ(0u, implDefCount % 2);
-        ASSERT_GE(implDefCount, 2u);
-
-        getResolutionList(HAL_PIXEL_FORMAT_BLOB, &jpegData, &jpegCount);
-        ASSERT_EQ(0u, jpegCount % 2);
-        ASSERT_GE(jpegCount, 2u);
-    }
-
-    camera_metadata_ro_entry hardwareLevel =
-        GetStaticEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
-    ASSERT_EQ(1u, hardwareLevel.count);
-    uint8_t level = hardwareLevel.data.u8[0];
-    ASSERT_GE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
-    ASSERT_LE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
-    if (level == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) {
-        const ::testing::TestInfo* const test_info =
-            ::testing::UnitTest::GetInstance()->current_test_info();
-        std::cerr << "Skipping test "
-                  << test_info->test_case_name() << "."
-                  << test_info->name()
-                  << " because HAL hardware supported level is limited "
-                  << std::endl;
-        return;
-    }
-
-    // Find the right sizes for preview, metering, and capture streams
-    int64_t minFrameDuration = DEFAULT_FRAME_DURATION;
-    Size processedMinSize = {0, 0}, processedMaxSize = {0, 0};
-    Size jpegMaxSize = {0, 0};
-
-    int32_t minIdx, maxIdx;
-    GetMinSize(implDefData, implDefCount, &processedMinSize, &minIdx);
-    GetMaxSize(implDefData, implDefCount, &processedMaxSize, &maxIdx);
-    ALOGV("Found processed max size: %dx%d, min size = %dx%d",
-            processedMaxSize.width, processedMaxSize.height,
-            processedMinSize.width, processedMinSize.height);
-
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-        camera_metadata_ro_entry availableProcessedMinFrameDurations =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
-        minFrameDuration =
-            availableProcessedMinFrameDurations.data.i64[maxIdx / 2];
-    } else {
-        minFrameDuration = getMinFrameDurationFor(
-                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-                processedMaxSize.width, processedMaxSize.height);
-    }
-
-    EXPECT_GT(minFrameDuration, 0);
-
-    if (minFrameDuration <= 0) {
-        minFrameDuration = DEFAULT_FRAME_DURATION;
-    }
-
-    ALOGV("targeted minimal frame duration is: %" PRId64 "ns", minFrameDuration);
-
-    GetMaxSize(jpegData, jpegCount, &jpegMaxSize, &maxIdx);
-    ALOGV("Found Jpeg size max idx = %d", maxIdx);
-
-    // Max Jpeg size should be available in processed sizes. Use it for
-    // YUV capture anyway.
-    EXPECT_EQ(processedMaxSize.width, jpegMaxSize.width);
-    EXPECT_EQ(processedMaxSize.height, jpegMaxSize.height);
-
-    // Cap preview size.
-    Size previewLimit = { PREVIEW_WIDTH_CAP, PREVIEW_HEIGHT_CAP };
-    // FIXME: need make sure the previewLimit is supported by HAL.
-    Size previewSize = CapSize(previewLimit, processedMaxSize);
-    // Cap Metering size.
-    Size meteringLimit = { METERING_WIDTH_CAP, METERING_HEIGHT_CAP };
-    // Cap metering size to VGA (VGA is mandatory by CDD)
-    Size meteringSize = CapSize(meteringLimit, processedMinSize);
-    // Capture stream should be the max size of jpeg sizes.
-    ALOGV("preview size: %dx%d, metering size: %dx%d, capture size: %dx%d",
-            previewSize.width, previewSize.height,
-            meteringSize.width, meteringSize.height,
-            jpegMaxSize.width, jpegMaxSize.height);
-
-    // Create streams
-    // Preview stream: small resolution, render on the screen.
-    sp<CameraStream> previewStream;
-    {
-        sp<Surface> surface;
-        ASSERT_NO_FATAL_FAILURE(CreateOnScreenSurface(/*out*/surface));
-        previewStream = CreateStream(
-                previewSize.width,
-                previewSize.height,
-                mDevice,
-                DISPLAY_STREAM_PARAMETERS,
-                surface,
-                false);
-        ASSERT_NE((void*)NULL, previewStream.get());
-        ASSERT_NO_FATAL_FAILURE(previewStream->SetUp());
-    }
-    // Metering burst stream: small resolution yuv stream
-    sp<CameraStream> meteringStream =
-            CreateStream(
-                    meteringSize.width,
-                    meteringSize.height,
-                    mDevice);
-    ASSERT_NE((void*)NULL, meteringStream.get());
-    ASSERT_NO_FATAL_FAILURE(meteringStream->SetUp());
-    // Capture burst stream: full resolution yuv stream
-    sp<CameraStream> captureStream =
-            CreateStream(
-                    jpegMaxSize.width,
-                    jpegMaxSize.height,
-                    mDevice);
-    ASSERT_NE((void*)NULL, captureStream.get());
-    ASSERT_NO_FATAL_FAILURE(captureStream->SetUp());
-
-    // Create Preview request.
-    CameraMetadata previewRequest, meteringRequest, captureRequest;
-    ASSERT_NO_FATAL_FAILURE(CreateRequests(previewRequest, meteringRequest,
-            captureRequest, previewStream->GetStreamId(),
-            meteringStream->GetStreamId(), captureStream->GetStreamId()));
-
-    // Start preview
-    if (CAMERA_MULTI_STREAM_DEBUGGING) {
-        previewRequest.dump(STDOUT_FILENO);
-    }
-
-    // Generate exposure and sensitivity lists
-    camera_metadata_ro_entry exposureTimeRange =
-        GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
-    ASSERT_EQ(exposureTimeRange.count, 2u);
-    int64_t minExp = exposureTimeRange.data.i64[0];
-    int64_t maxExp = exposureTimeRange.data.i64[1];
-    ASSERT_GT(maxExp, minExp);
-
-    camera_metadata_ro_entry sensivityRange =
-        GetStaticEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
-    ASSERT_EQ(2u, sensivityRange.count);
-    int32_t minSensitivity = sensivityRange.data.i32[0];
-    int32_t maxSensitivity = sensivityRange.data.i32[1];
-    camera_metadata_ro_entry maxAnalogSenEntry =
-            GetStaticEntry(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY);
-    EXPECT_EQ(1u, maxAnalogSenEntry.count);
-    int32_t maxAnalogSensitivity = maxAnalogSenEntry.data.i32[0];
-    EXPECT_LE(maxAnalogSensitivity, maxSensitivity);
-    // Only test the sensitivity implemented by analog gain.
-    if (maxAnalogSensitivity > maxSensitivity) {
-        // Fallback to maxSensitity
-        maxAnalogSensitivity = maxSensitivity;
-    }
-
-    // sensitivity list, only include the sensitivities that are implemented
-    // purely by analog gain if possible.
-    Vector<int32_t> sensitivities;
-    Vector<int64_t> exposures;
-    size_t count = (maxAnalogSensitivity - minSensitivity + 99) / 100;
-    sensitivities.push_back(minSensitivity);
-    for (size_t i = 1; i < count; i++) {
-        sensitivities.push_back(minSensitivity + i * 100);
-    }
-    sensitivities.push_back(maxAnalogSensitivity);
-    ALOGV("Sensitivity Range: min=%d, max=%d", minSensitivity,
-            maxAnalogSensitivity);
-    int64_t exp = minExp;
-    while (exp < maxExp) {
-        exposures.push_back(exp);
-        exp *= 2;
-    }
-    // Sweep the exposure value for preview, just for visual inspection purpose.
-    uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-    for (size_t i = 0; i < exposures.size(); i++) {
-        ASSERT_EQ(OK, previewRequest.update(
-                ANDROID_CONTROL_MODE,
-                &cmOff, 1));
-        ASSERT_EQ(OK, previewRequest.update(
-                ANDROID_SENSOR_EXPOSURE_TIME,
-                &exposures[i], 1));
-        ALOGV("Submitting preview request %zu with exposure %" PRId64,
-                i, exposures[i]);
-
-        ASSERT_EQ(OK, mDevice->setStreamingRequest(previewRequest));
-
-        // Let preview run 200ms on screen for each exposure time.
-        usleep(PREVIEW_RENDERING_TIME_INTERVAL);
-    }
-
-    size_t requestCount = sensitivities.size();
-    if (requestCount > exposures.size()) {
-        requestCount = exposures.size();
-    }
-
-    // To maintain the request id uniqueness (preview request id is 0), make burst capture start
-    // request id 1 here.
-    int32_t requestIdStart = 1;
-    /**
-     * Submit metering request, set default frame duration to minimal possible
-     * value, we want the capture to run as fast as possible. HAL should adjust
-     * the frame duration to minimal necessary value to support the requested
-     * exposure value if exposure is larger than frame duration.
-     */
-    CaptureBurst(meteringRequest, requestCount, exposures, sensitivities,
-            meteringStream, minFrameDuration, &requestIdStart);
-
-    /**
-     * Submit capture request, set default frame duration to minimal possible
-     * value, we want the capture to run as fast as possible. HAL should adjust
-     * the frame duration to minimal necessary value to support the requested
-     * exposure value if exposure is larger than frame duration.
-     */
-    CaptureBurst(captureRequest, requestCount, exposures, sensitivities,
-            captureStream, minFrameDuration, &requestIdStart);
-
-    ASSERT_EQ(OK, mDevice->clearStreamingRequest());
-}
-
-}
-}
-}
diff --git a/tests/camera2/CameraStreamFixture.h b/tests/camera2/CameraStreamFixture.h
deleted file mode 100644
index 92ff05b..0000000
--- a/tests/camera2/CameraStreamFixture.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __ANDROID_HAL_CAMERA2_TESTS_STREAM_FIXTURE__
-#define __ANDROID_HAL_CAMERA2_TESTS_STREAM_FIXTURE__
-
-#include <gtest/gtest.h>
-#include <iostream>
-#include <fstream>
-
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
-#include <system/camera_metadata.h>
-
-#include "CameraModuleFixture.h"
-#include "TestExtensions.h"
-
-#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-// Format specifier for picking the best format for CPU reading the given device
-// version
-#define CAMERA_STREAM_AUTO_CPU_FORMAT (-1)
-
-struct CameraStreamParams;
-
-void PrintTo(const CameraStreamParams& p, ::std::ostream* os);
-
-struct CameraStreamParams {
-    int mFormat;
-    int mHeapCount;
-
-};
-
-inline ::std::ostream& operator<<(::std::ostream& os, const CameraStreamParams &p) {
-    PrintTo(p, &os);
-    return os;
-}
-
-inline void PrintTo(const CameraStreamParams& p, ::std::ostream* os) {
-    char fmt[100];
-    camera_metadata_enum_snprint(
-        ANDROID_SCALER_AVAILABLE_FORMATS, p.mFormat, fmt, sizeof(fmt));
-
-    *os <<  "{ ";
-    *os <<  "Format: 0x"  << std::hex << p.mFormat    << ", ";
-    *os <<  "Format name: " << fmt << ", ";
-    *os <<  "HeapCount: " <<             p.mHeapCount;
-    *os << " }";
-}
-
-class CameraStreamFixture
-    : public CameraModuleFixture</*InfoQuirk*/true> {
-
-public:
-    explicit CameraStreamFixture(CameraStreamParams p)
-    : CameraModuleFixture(TestSettings::DeviceId()) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        mParam = p;
-
-        SetUp();
-    }
-
-    ~CameraStreamFixture() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-
-        TearDown();
-    }
-
-private:
-
-    void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-
-        CameraModuleFixture::SetUp();
-
-        sp<CameraDeviceBase> device = mDevice;
-
-        /* use an arbitrary w,h */
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            const int tag = ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES;
-
-            const CameraMetadata& staticInfo = device->info();
-            camera_metadata_ro_entry entry = staticInfo.find(tag);
-            ASSERT_NE(0u, entry.count)
-                << "Missing tag android.scaler.availableProcessedSizes";
-
-            ASSERT_LE(2u, entry.count);
-            /* this seems like it would always be the smallest w,h
-               but we actually make no contract that it's sorted asc */
-            mWidth = entry.data.i32[0];
-            mHeight = entry.data.i32[1];
-        } else {
-            buildOutputResolutions();
-            const int32_t *implDefResolutions = NULL;
-            size_t   implDefResolutionsCount;
-
-            int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
-
-            getResolutionList(format,
-                    &implDefResolutions, &implDefResolutionsCount);
-            ASSERT_NE(0u, implDefResolutionsCount)
-                << "Missing implementation defined sizes";
-            mWidth = implDefResolutions[0];
-            mHeight = implDefResolutions[1];
-        }
-    }
-    void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-
-        // important: shut down HAL before releasing streams
-        CameraModuleFixture::TearDown();
-
-        deleteOutputResolutions();
-        mSurface.clear();
-        mCpuConsumer.clear();
-        mFrameListener.clear();
-    }
-
-protected:
-
-    int64_t getMinFrameDurationFor(int32_t format, int32_t width, int32_t height) {
-        int64_t minFrameDuration = -1L;
-        const int tag = ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
-        sp<CameraDeviceBase> device = mDevice;
-        const CameraMetadata& staticInfo = device->info();
-        camera_metadata_ro_entry_t availableMinDurations = staticInfo.find(tag);
-        for (uint32_t i = 0; i < availableMinDurations.count; i += 4) {
-            if (format == availableMinDurations.data.i64[i] &&
-                    width == availableMinDurations.data.i64[i + 1] &&
-                    height == availableMinDurations.data.i64[i + 2]) {
-                minFrameDuration = availableMinDurations.data.i64[i + 3];
-                break;
-            }
-        }
-        return minFrameDuration;
-    }
-
-    void buildOutputResolutions() {
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            return;
-        }
-        if (mOutputResolutions.isEmpty()) {
-            const int tag = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
-            const CameraMetadata& staticInfo = mDevice->info();
-            camera_metadata_ro_entry_t availableStrmConfigs = staticInfo.find(tag);
-            ASSERT_EQ(0u, availableStrmConfigs.count % 4);
-            for (uint32_t i = 0; i < availableStrmConfigs.count; i += 4) {
-                int32_t format = availableStrmConfigs.data.i32[i];
-                int32_t width = availableStrmConfigs.data.i32[i + 1];
-                int32_t height = availableStrmConfigs.data.i32[i + 2];
-                int32_t inOrOut = availableStrmConfigs.data.i32[i + 3];
-                if (inOrOut == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
-                    int index = mOutputResolutions.indexOfKey(format);
-                    if (index < 0) {
-                        index = mOutputResolutions.add(format, new Vector<int32_t>());
-                        ASSERT_TRUE(index >= 0);
-                    }
-                    Vector<int32_t> *resolutions = mOutputResolutions.editValueAt(index);
-                    resolutions->add(width);
-                    resolutions->add(height);
-                }
-            }
-        }
-    }
-
-    void getResolutionList(int32_t format,
-            const int32_t **list,
-            size_t *count) {
-        ALOGV("Getting resolutions for format %x", format);
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            return;
-        }
-        int index = mOutputResolutions.indexOfKey(format);
-        ASSERT_TRUE(index >= 0);
-        Vector<int32_t>* resolutions = mOutputResolutions.valueAt(index);
-        *list = resolutions->array();
-        *count = resolutions->size();
-    }
-
-    void deleteOutputResolutions() {
-        for (uint32_t i = 0; i < mOutputResolutions.size(); i++) {
-            Vector<int32_t>* resolutions = mOutputResolutions.editValueAt(i);
-            delete resolutions;
-        }
-        mOutputResolutions.clear();
-    }
-
-    struct FrameListener : public ConsumerBase::FrameAvailableListener {
-
-        FrameListener() {
-            mPendingFrames = 0;
-        }
-
-        // CpuConsumer::FrameAvailableListener implementation
-        virtual void onFrameAvailable(const BufferItem& /* item */) {
-            ALOGV("Frame now available (start)");
-
-            Mutex::Autolock lock(mMutex);
-            mPendingFrames++;
-            mCondition.signal();
-
-            ALOGV("Frame now available (end)");
-        }
-
-        status_t waitForFrame(nsecs_t timeout) {
-            status_t res;
-            Mutex::Autolock lock(mMutex);
-            while (mPendingFrames == 0) {
-                res = mCondition.waitRelative(mMutex, timeout);
-                if (res != OK) return res;
-            }
-            mPendingFrames--;
-            return OK;
-        }
-
-    private:
-        Mutex mMutex;
-        Condition mCondition;
-        int mPendingFrames;
-    };
-
-    void CreateStream() {
-        sp<CameraDeviceBase> device = mDevice;
-        CameraStreamParams p = mParam;
-
-        sp<IGraphicBufferProducer> producer;
-        sp<IGraphicBufferConsumer> consumer;
-        BufferQueue::createBufferQueue(&producer, &consumer);
-        mCpuConsumer = new CpuConsumer(consumer, p.mHeapCount);
-        mCpuConsumer->setName(String8("CameraStreamTest::mCpuConsumer"));
-
-        mSurface = new Surface(producer);
-
-        int format = MapAutoFormat(p.mFormat);
-
-        ASSERT_EQ(OK,
-            device->createStream(mSurface,
-                mWidth, mHeight, format,
-                HAL_DATASPACE_UNKNOWN,
-                CAMERA3_STREAM_ROTATION_0,
-                &mStreamId));
-
-        ASSERT_NE(-1, mStreamId);
-
-        // do not make 'this' a FrameListener or the lifetime policy will clash
-        mFrameListener = new FrameListener();
-        mCpuConsumer->setFrameAvailableListener(mFrameListener);
-    }
-
-    void DeleteStream() {
-        ASSERT_EQ(OK, mDevice->deleteStream(mStreamId));
-    }
-
-    int MapAutoFormat(int format) {
-        if (format == CAMERA_STREAM_AUTO_CPU_FORMAT) {
-            if (getDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
-                format = HAL_PIXEL_FORMAT_YCbCr_420_888;
-            } else {
-                format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
-            }
-        }
-        return format;
-    }
-
-    void DumpYuvToFile(const String8 &fileName, const CpuConsumer::LockedBuffer &img) {
-        uint8_t *dataCb, *dataCr;
-        uint32_t stride;
-        uint32_t chromaStride;
-        uint32_t chromaStep;
-
-        switch (img.format) {
-            case HAL_PIXEL_FORMAT_YCbCr_420_888:
-                stride = img.stride;
-                chromaStride = img.chromaStride;
-                chromaStep = img.chromaStep;
-                dataCb = img.dataCb;
-                dataCr = img.dataCr;
-                break;
-            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-                stride = img.width;
-                chromaStride = img.width;
-                chromaStep = 2;
-                dataCr = img.data + img.width * img.height;
-                dataCb = dataCr + 1;
-                break;
-            case HAL_PIXEL_FORMAT_YV12:
-                stride = img.stride;
-                chromaStride = ALIGN(img.width / 2, 16);
-                chromaStep = 1;
-                dataCr = img.data + img.stride * img.height;
-                dataCb = dataCr + chromaStride * img.height/2;
-                break;
-            default:
-                ALOGE("Unknown format %d, not dumping", img.format);
-                return;
-        }
-
-        // Write Y
-        FILE *yuvFile = fopen(fileName.string(), "w");
-
-        size_t bytes;
-
-        for (size_t y = 0; y < img.height; ++y) {
-            bytes = fwrite(
-                reinterpret_cast<const char*>(img.data + stride * y),
-                1, img.width, yuvFile);
-            if (bytes != img.width) {
-                ALOGE("Unable to write to file %s", fileName.string());
-                fclose(yuvFile);
-                return;
-            }
-        }
-
-        // Write Cb/Cr
-        uint8_t *src = dataCb;
-        for (int c = 0; c < 2; ++c) {
-            for (size_t y = 0; y < img.height / 2; ++y) {
-                uint8_t *px = src + y * chromaStride;
-                if (chromaStep != 1) {
-                    for (size_t x = 0; x < img.width / 2; ++x) {
-                        fputc(*px, yuvFile);
-                        px += chromaStep;
-                    }
-                } else {
-                    bytes = fwrite(reinterpret_cast<const char*>(px),
-                            1, img.width / 2, yuvFile);
-                    if (bytes != img.width / 2) {
-                        ALOGE("Unable to write to file %s", fileName.string());
-                        fclose(yuvFile);
-                        return;
-                    }
-                }
-            }
-            src = dataCr;
-        }
-        fclose(yuvFile);
-    }
-
-    int mWidth;
-    int mHeight;
-
-    int mStreamId;
-
-    android::sp<FrameListener>       mFrameListener;
-    android::sp<CpuConsumer>         mCpuConsumer;
-    android::sp<Surface>             mSurface;
-    KeyedVector<int32_t, Vector<int32_t>* > mOutputResolutions;
-
-private:
-    CameraStreamParams mParam;
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/CameraStreamTests.cpp b/tests/camera2/CameraStreamTests.cpp
deleted file mode 100644
index de9ae8a..0000000
--- a/tests/camera2/CameraStreamTests.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.
- */
-
-#include <iostream>
-#include <iomanip>
-#include <gtest/gtest.h>
-
-#define LOG_TAG "CameraStreamTest"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include <utils/StrongPointer.h>
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-using namespace android;
-using namespace android::camera2;
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-class CameraStreamTest
-    : public ::testing::TestWithParam<CameraStreamParams>,
-      public CameraStreamFixture {
-
-public:
-    CameraStreamTest() : CameraStreamFixture(GetParam()) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-    }
-
-    ~CameraStreamTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-
-protected:
-
-};
-
-TEST_P(CameraStreamTest, CreateStream) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    /** Make sure the format requested is supported. PASS this test if it's not
-      * not supported.
-      *
-      * TODO: would be nice of not running this test in the first place
-      *       somehow.
-      */
-    {
-        camera_metadata_ro_entry availableFormats =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_FORMATS);
-
-        bool hasFormat = false;
-        for (size_t i = 0; i < availableFormats.count; ++i) {
-            if (availableFormats.data.i32[i] == GetParam().mFormat) {
-                hasFormat = true;
-                break;
-            }
-        }
-
-        if (!hasFormat) {
-            const ::testing::TestInfo* const test_info =
-                ::testing::UnitTest::GetInstance()->current_test_info();
-            std::cerr << "Skipping test "
-                      << test_info->test_case_name() << "."
-                      << test_info->name()
-                      << " because the format was not available: "
-                      << GetParam() << std::endl;
-            return;
-        }
-    }
-
-    ASSERT_NO_FATAL_FAILURE(CreateStream());
-    ASSERT_NO_FATAL_FAILURE(DeleteStream());
-}
-
-//TODO: use a combinatoric generator
-static CameraStreamParams TestParameters[] = {
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP, // NV21
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
-        /*mHeapCount*/ 3
-    },
-};
-
-INSTANTIATE_TEST_CASE_P(StreamParameterCombinations, CameraStreamTest,
-    testing::ValuesIn(TestParameters));
-
-
-}
-}
-}
diff --git a/tests/camera2/ForkedTests.cpp b/tests/camera2/ForkedTests.cpp
deleted file mode 100644
index 39599da..0000000
--- a/tests/camera2/ForkedTests.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.
- */
-
-#include <gtest/gtest.h>
-
-#include <stdlib.h>
-
-#include "TestExtensions.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-// Intentionally disabled since 2 of these tests are supposed to fail
-class DISABLED_ForkedTest : public ::testing::Test {
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-};
-
-// intentionally fail
-TEST_F(DISABLED_ForkedTest, FailCrash) {
-    TEST_EXTENSION_FORKING_INIT;
-    abort();
-}
-
-TEST_F(DISABLED_ForkedTest, SucceedNormal) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    EXPECT_TRUE(true);
-}
-
-// intentionally fail
-TEST_F(DISABLED_ForkedTest, FailNormal) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    EXPECT_TRUE(false);
-}
-
-}
-}
-}
-
diff --git a/tests/camera2/TestExtensions.h b/tests/camera2/TestExtensions.h
deleted file mode 100644
index 2af587d..0000000
--- a/tests/camera2/TestExtensions.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __ANDROID_HAL_CAMERA2_TESTS_EXTENSIONS__
-#define __ANDROID_HAL_CAMERA2_TESTS_EXTENSIONS__
-
-#include "TestForkerEventListener.h"
-#include "TestSettings.h"
-
-// Use at the beginning of each Test::SetUp() impl
-#define TEST_EXTENSION_FORKING_SET_UP                                       \
-    do {                                                                    \
-        if (TEST_EXTENSION_FORKING_ENABLED) {                               \
-            if (!TestForkerEventListener::mIsForked) {                      \
-                return;                                                     \
-            }                                                               \
-        }                                                                   \
-    } while (false)                                                         \
-
-// Use at the beginning of each Test::TearDown() impl
-#define TEST_EXTENSION_FORKING_TEAR_DOWN   TEST_EXTENSION_FORKING_SET_UP
-
-// Use at the beginning of each Test::Test constructor
-#define TEST_EXTENSION_FORKING_CONSTRUCTOR TEST_EXTENSION_FORKING_SET_UP
-
-// Use at the beginning of each Test::~Test destructor
-#define TEST_EXTENSION_FORKING_DESTRUCTOR  TEST_EXTENSION_FORKING_TEAR_DOWN
-
-// Use at the beginning of each test body, e.g. TEST(x,y), TEST_F(x,y), etc
-#define TEST_EXTENSION_FORKING_INIT                                         \
-    do {                                                                    \
-        TEST_EXTENSION_FORKING_SET_UP;                                      \
-        if (HasFatalFailure()) return;                                      \
-    } while(false)                                                          \
-
-// Are we running each test by forking it?
-#define TEST_EXTENSION_FORKING_ENABLED                                      \
-    (android::camera2::tests::TestSettings::ForkingEnabled())
-
-
-
-#endif
-
diff --git a/tests/camera2/TestForkerEventListener.cpp b/tests/camera2/TestForkerEventListener.cpp
deleted file mode 100644
index 9416db2..0000000
--- a/tests/camera2/TestForkerEventListener.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.
- */
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <string.h>
-
-#include <gtest/gtest.h>
-
-#include "TestForkerEventListener.h"
-#include "TestExtensions.h"
-
-#define DEBUG_TEST_FORKER_EVENT_LISTENER 0
-
-#define RETURN_CODE_PASSED 0
-#define RETURN_CODE_FAILED 1
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-bool TestForkerEventListener::mIsForked         = false;
-
-TestForkerEventListener::TestForkerEventListener() {
-    mIsForked = false;
-    mHasSucceeded = true;
-    mTermSignal = 0;
-}
-
-// Called before a test starts.
-void TestForkerEventListener::OnTestStart(const ::testing::TestInfo&) {
-
-    if (!TEST_EXTENSION_FORKING_ENABLED) {
-        return;
-    }
-
-    pid_t childPid = fork();
-    if (childPid != 0) {
-        int status;
-        waitpid(childPid, &status, /*options*/0);
-
-        // terminated normally?
-        mHasSucceeded = WIFEXITED(status);
-        // terminate with return code 0 = test passed, 1 = test failed
-        if (mHasSucceeded) {
-          mHasSucceeded = WEXITSTATUS(status) == RETURN_CODE_PASSED;
-        } else if (WIFSIGNALED(status)) {
-          mTermSignal = WTERMSIG(status);
-        }
-
-        /* the test is then skipped by inserting the various
-        TEST_EXTENSION_ macros in TestExtensions.h */
-
-    } else {
-        mIsForked = true;
-    }
-}
-
-// Called after a failed assertion or a SUCCEED() invocation.
-void TestForkerEventListener::OnTestPartResult(
-    const ::testing::TestPartResult& test_part_result) {
-
-    if (DEBUG_TEST_FORKER_EVENT_LISTENER) {
-        printf("%s in %s:%d\n%s\n",
-             test_part_result.failed() ? "*** Failure" : "Success",
-             test_part_result.file_name(),
-             test_part_result.line_number(),
-             test_part_result.summary());
-    }
-}
-
-// Called after a test ends.
-void TestForkerEventListener::OnTestEnd(const ::testing::TestInfo& test_info) {
-
-    if (!TEST_EXTENSION_FORKING_ENABLED) {
-        return;
-    }
-
-    if (mIsForked) {
-        exit(test_info.result()->Passed()
-            ? RETURN_CODE_PASSED : RETURN_CODE_FAILED);
-    } else if (!mHasSucceeded && mTermSignal != 0) {
-
-      printf("*** Test %s.%s crashed with signal = %s\n",
-             test_info.test_case_name(), test_info.name(),
-             strsignal(mTermSignal));
-    }
-
-    //TODO: overload the default event listener to suppress this message
-    // dynamically (e.g. by skipping OnTestPartResult after OnTestEnd )
-
-    // trigger a test failure if the child has failed
-    if (!mHasSucceeded) {
-        ADD_FAILURE();
-    }
-    mTermSignal = 0;
-}
-
-
-}
-}
-}
-
diff --git a/tests/camera2/TestForkerEventListener.h b/tests/camera2/TestForkerEventListener.h
deleted file mode 100644
index 347a06b..0000000
--- a/tests/camera2/TestForkerEventListener.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __ANDROID_HAL_CAMERA2_TESTS_FORKER_EVENT_LISTENER__
-#define __ANDROID_HAL_CAMERA2_TESTS_FORKER_EVENT_LISTENER__
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-// Fork before each test runs.
-class TestForkerEventListener : public ::testing::EmptyTestEventListener {
-
-public:
-
-    TestForkerEventListener();
-
-private:
-
-    // Called before a test starts.
-    virtual void OnTestStart(const ::testing::TestInfo& test_info);
-
-    // Called after a failed assertion or a SUCCEED() invocation.
-    virtual void OnTestPartResult(
-        const ::testing::TestPartResult& test_part_result);
-
-    // Called after a test ends.
-    virtual void OnTestEnd(const ::testing::TestInfo& test_info);
-
-    bool mHasSucceeded;
-    int mTermSignal;
-
-public:
-    // do not read directly. use TEST_EXTENSION macros instead
-    static bool mIsForked;
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/TestSettings.cpp b/tests/camera2/TestSettings.cpp
deleted file mode 100644
index f07adc8..0000000
--- a/tests/camera2/TestSettings.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.
- */
-
-#include <cstdlib>
-#include <getopt.h>
-#include <cstring>
-#include <iostream>
-
-#include "TestSettings.h"
-
-#include "TestForkerEventListener.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-bool TestSettings::mForkingDisabled     = false;
-int  TestSettings::mDeviceId            = 0;
-char* const* TestSettings::mArgv;
-
-// --forking-disabled, false by default
-bool TestSettings::ForkingDisabled() {
-    return mForkingDisabled;
-}
-
-// reverse of --forking-disabled (not a flag), true by default
-bool TestSettings::ForkingEnabled() {
-    return !ForkingDisabled();
-}
-
-// --device-id, 0 by default
-int TestSettings::DeviceId() {
-    return mDeviceId;
-}
-
-// returns false if usage should be printed and we should exit early
-bool TestSettings::ParseArgs(int argc, char* const argv[])
-{
-    {
-        char *env = getenv("CAMERA2_TEST_FORKING_DISABLED");
-        if (env) {
-            mForkingDisabled = atoi(env);
-        }
-
-        env = getenv("CAMERA2_TEST_DEVICE_ID");
-        if (env) {
-            mDeviceId = atoi(env);
-        }
-    }
-
-    bool printHelp = false;
-    bool unknownArgs = false;
-
-    opterr = 0; // do not print errors for unknown arguments
-    while (true) {
-        int c;
-        int option_index = 0;
-
-        static struct option long_options[] = {
-            /* name              has_arg          flag val */
-            {"forking-disabled", optional_argument, 0,  0  },
-            {"device-id",        required_argument, 0,  0  },
-            {"help",             no_argument,       0, 'h' },
-            {0,                  0,                 0,  0  }
-        };
-
-        // Note: '+' in optstring means do not mutate argv
-        c = getopt_long(argc, argv, "+h", long_options, &option_index);
-
-        if (c == -1) { // All arguments exhausted
-            break;
-        }
-        if (c == '?') { // Argument not in option lists
-            const char *arg = argv[optind-1];
-            // Anything beginning with gtest_ will get handled by gtest
-            if (strstr(arg, "--gtest_") != arg) {
-                std::cerr << "Unknown argument: " << arg << std::endl;
-                unknownArgs = true;
-            }
-            continue;
-        }
-
-        switch (c) {
-        case 0: // long option
-            switch (option_index) {
-            case 0: {
-                const char *arg = optarg ?: "1";
-                mForkingDisabled = atoi(arg);
-                break;
-            }
-            case 1: {
-                mDeviceId = atoi(optarg);
-                break;
-            }
-            default:
-                std::cerr << "Unknown long option: " << option_index << std::endl;
-                break;
-            }
-            break; // case 0
-        case 'h': // help
-            printHelp = true;
-            break;
-        default: // case '?'
-            std::cerr << "Unknown option: " << optarg << std::endl;
-        }
-    }
-
-    if (unknownArgs) {
-        std::cerr << std::endl;
-    }
-
-    mArgv = argv;
-
-    if (printHelp || unknownArgs) {
-        return false;
-    }
-
-    std::cerr << "Forking Disabled: "
-              << (mForkingDisabled ? "yes" : "no") << std::endl;
-
-    std::cerr << "Device ID: " << mDeviceId << std::endl;
-
-    return true;
-}
-
-// print usage/help list of commands (non-gtest)
-void TestSettings::PrintUsage() {
-    std::cerr << "Usage: " << mArgv[0] << " [OPTIONS]" << std::endl;
-    std::cerr << std::endl;
-
-    std::cerr << "Main modes of operation:"
-              << std::endl;
-    std::cerr << "   --forking-disabled[=1]  don't fork process before "
-              << std::endl
-              << "                           running a new test."
-              << std::endl
-              << "                           (default enabled)"
-              << std::endl;
-    std::cerr << "   --device-id=ID          specify a different camera ID"
-              << std::endl
-              << "                           (default 0)"
-              << std::endl;
-
-    std::cerr << "   -h, --help              print this help listing"
-              << std::endl;
-
-
-    std::cerr << std::endl;
-}
-
-}
-}
-}
-
diff --git a/tests/camera2/TestSettings.h b/tests/camera2/TestSettings.h
deleted file mode 100644
index 6164de5..0000000
--- a/tests/camera2/TestSettings.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-:qa
- * 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.
- */
-
-#ifndef __ANDROID_HAL_CAMERA2_TESTS_SETTINGS__
-#define __ANDROID_HAL_CAMERA2_TESTS_SETTINGS__
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-class TestSettings {
-
-public:
-    // --forking-disabled, false by default
-    static bool ForkingDisabled();
-
-    // reverse of --forking-disabled (not a flag), true by default
-    static bool ForkingEnabled();
-
-    // --device-id, 0 by default
-    static int DeviceId();
-
-    // returns false if usage should be printed and we should exit early
-    static bool ParseArgs(int argc, char* const argv[]);
-
-    // print usage/help list of commands (non-gtest)
-    static void PrintUsage();
-
-private:
-    TestSettings();
-    ~TestSettings();
-
-    static bool mForkingDisabled;
-    static int  mDeviceId;
-    static char* const* mArgv;
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/camera2_utils.cpp b/tests/camera2/camera2_utils.cpp
deleted file mode 100644
index dab0ae9..0000000
--- a/tests/camera2/camera2_utils.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * 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.
- */
-
-// Utility classes for camera2 HAL testing
-
-#define LOG_TAG "Camera2_test_utils"
-#define LOG_NDEBUG 0
-
-#include "utils/Log.h"
-#include "camera2_utils.h"
-#include <dlfcn.h>
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-/**
- * MetadataQueue
- */
-
-MetadataQueue::MetadataQueue():
-            mDevice(NULL),
-            mFrameCount(0),
-            mCount(0),
-            mStreamSlotCount(0),
-            mSignalConsumer(true)
-{
-    camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
-    camera2_request_queue_src_ops::request_count = consumer_buffer_count;
-    camera2_request_queue_src_ops::free_request = consumer_free;
-
-    camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
-    camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
-    camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
-}
-
-MetadataQueue::~MetadataQueue() {
-    freeBuffers(mEntries.begin(), mEntries.end());
-    freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
-}
-
-// Interface to camera2 HAL as consumer (input requests/reprocessing)
-const camera2_request_queue_src_ops_t* MetadataQueue::getToConsumerInterface() {
-    return static_cast<camera2_request_queue_src_ops_t*>(this);
-}
-
-void MetadataQueue::setFromConsumerInterface(camera2_device_t *d) {
-    mDevice = d;
-}
-
-const camera2_frame_queue_dst_ops_t* MetadataQueue::getToProducerInterface() {
-    return static_cast<camera2_frame_queue_dst_ops_t*>(this);
-}
-
-// Real interfaces
-status_t MetadataQueue::enqueue(camera_metadata_t *buf) {
-    Mutex::Autolock l(mMutex);
-
-    mCount++;
-    mEntries.push_back(buf);
-    notEmpty.signal();
-
-    if (mSignalConsumer && mDevice != NULL) {
-        mSignalConsumer = false;
-
-        mMutex.unlock();
-        ALOGV("%s: Signaling consumer", __FUNCTION__);
-        mDevice->ops->notify_request_queue_not_empty(mDevice);
-        mMutex.lock();
-    }
-    return OK;
-}
-
-int MetadataQueue::getBufferCount() {
-    Mutex::Autolock l(mMutex);
-    if (mStreamSlotCount > 0) {
-        return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
-    }
-    return mCount;
-}
-
-status_t MetadataQueue::dequeue(camera_metadata_t **buf, bool incrementCount) {
-    Mutex::Autolock l(mMutex);
-
-    if (mCount == 0) {
-        if (mStreamSlotCount == 0) {
-            ALOGV("%s: Empty", __FUNCTION__);
-            *buf = NULL;
-            mSignalConsumer = true;
-            return OK;
-        }
-        ALOGV("%s: Streaming %d frames to queue", __FUNCTION__,
-              mStreamSlotCount);
-
-        for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
-                slotEntry != mStreamSlot.end();
-                slotEntry++ ) {
-            size_t entries = get_camera_metadata_entry_count(*slotEntry);
-            size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
-
-            camera_metadata_t *copy = allocate_camera_metadata(entries, dataBytes);
-            append_camera_metadata(copy, *slotEntry);
-            mEntries.push_back(copy);
-        }
-        mCount = mStreamSlotCount;
-    }
-    ALOGV("MetadataQueue: deque (%d buffers)", mCount);
-    camera_metadata_t *b = *(mEntries.begin());
-    mEntries.erase(mEntries.begin());
-
-    if (incrementCount) {
-        add_camera_metadata_entry(b,
-                ANDROID_REQUEST_FRAME_COUNT,
-                (void**)&mFrameCount, 1);
-        mFrameCount++;
-    }
-
-    *buf = b;
-    mCount--;
-
-    return OK;
-}
-
-status_t MetadataQueue::waitForBuffer(nsecs_t timeout) {
-    Mutex::Autolock l(mMutex);
-    status_t res;
-    while (mCount == 0) {
-        res = notEmpty.waitRelative(mMutex,timeout);
-        if (res != OK) return res;
-    }
-    return OK;
-}
-
-status_t MetadataQueue::setStreamSlot(camera_metadata_t *buf) {
-    if (buf == NULL) {
-        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
-        mStreamSlotCount = 0;
-        return OK;
-    }
-    if (mStreamSlotCount > 1) {
-        List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
-        freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
-        mStreamSlotCount = 1;
-    }
-    if (mStreamSlotCount == 1) {
-        free_camera_metadata( *(mStreamSlot.begin()) );
-        *(mStreamSlot.begin()) = buf;
-    } else {
-        mStreamSlot.push_front(buf);
-        mStreamSlotCount = 1;
-    }
-    return OK;
-}
-
-status_t MetadataQueue::setStreamSlot(const List<camera_metadata_t*> &bufs) {
-    if (mStreamSlotCount > 0) {
-        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
-    }
-    mStreamSlot = bufs;
-    mStreamSlotCount = mStreamSlot.size();
-
-    return OK;
-}
-
-status_t MetadataQueue::freeBuffers(List<camera_metadata_t*>::iterator start,
-                                    const List<camera_metadata_t*>::iterator& end) {
-    while (start != end) {
-        free_camera_metadata(*start);
-        start = mStreamSlot.erase(start);
-    }
-    return OK;
-}
-
-MetadataQueue* MetadataQueue::getInstance(
-        const camera2_request_queue_src_ops_t *q) {
-    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
-    return const_cast<MetadataQueue*>(cmq);
-}
-
-MetadataQueue* MetadataQueue::getInstance(
-        const camera2_frame_queue_dst_ops_t *q) {
-    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
-    return const_cast<MetadataQueue*>(cmq);
-}
-
-int MetadataQueue::consumer_buffer_count(
-        const camera2_request_queue_src_ops_t *q) {
-    MetadataQueue *queue = getInstance(q);
-    return queue->getBufferCount();
-}
-
-int MetadataQueue::consumer_dequeue(const camera2_request_queue_src_ops_t *q,
-        camera_metadata_t **buffer) {
-    MetadataQueue *queue = getInstance(q);
-    return queue->dequeue(buffer, true);
-}
-
-int MetadataQueue::consumer_free(const camera2_request_queue_src_ops_t * /* q */,
-        camera_metadata_t *old_buffer) {
-    free_camera_metadata(old_buffer);
-    return OK;
-}
-
-int MetadataQueue::producer_dequeue(const camera2_frame_queue_dst_ops_t * /* q */,
-        size_t entries, size_t bytes,
-        camera_metadata_t **buffer) {
-    camera_metadata_t *new_buffer =
-            allocate_camera_metadata(entries, bytes);
-    if (new_buffer == NULL) return NO_MEMORY;
-    *buffer = new_buffer;
-        return OK;
-}
-
-int MetadataQueue::producer_cancel(const camera2_frame_queue_dst_ops_t * /* q */,
-        camera_metadata_t *old_buffer) {
-    free_camera_metadata(old_buffer);
-    return OK;
-}
-
-int MetadataQueue::producer_enqueue(const camera2_frame_queue_dst_ops_t *q,
-        camera_metadata_t *filled_buffer) {
-    MetadataQueue *queue = getInstance(q);
-    return queue->enqueue(filled_buffer);
-}
-
-/**
- * NotifierListener
- */
-
-NotifierListener::NotifierListener() {
-}
-
-status_t NotifierListener::getNotificationsFrom(camera2_device *dev) {
-    if (!dev) return BAD_VALUE;
-    status_t err;
-    err = dev->ops->set_notify_callback(dev,
-            notify_callback_dispatch,
-            (void*)this);
-    return err;
-}
-
-status_t NotifierListener::getNextNotification(int32_t *msg_type,
-        int32_t *ext1,
-        int32_t *ext2,
-        int32_t *ext3) {
-    Mutex::Autolock l(mMutex);
-    if (mNotifications.size() == 0) return BAD_VALUE;
-    return getNextNotificationLocked(msg_type, ext1, ext2, ext3);
-}
-
-status_t NotifierListener::waitForNotification(int32_t *msg_type,
-        int32_t *ext1,
-        int32_t *ext2,
-        int32_t *ext3) {
-    Mutex::Autolock l(mMutex);
-    while (mNotifications.size() == 0) {
-        mNewNotification.wait(mMutex);
-    }
-    return getNextNotificationLocked(msg_type, ext1, ext2, ext3);
-}
-
-int NotifierListener::numNotifications() {
-    Mutex::Autolock l(mMutex);
-    return mNotifications.size();
-}
-
-status_t NotifierListener::getNextNotificationLocked(int32_t *msg_type,
-        int32_t *ext1,
-        int32_t *ext2,
-        int32_t *ext3) {
-    *msg_type = mNotifications.begin()->msg_type;
-    *ext1 = mNotifications.begin()->ext1;
-    *ext2 = mNotifications.begin()->ext2;
-    *ext3 = mNotifications.begin()->ext3;
-    mNotifications.erase(mNotifications.begin());
-    return OK;
-}
-
-void NotifierListener::onNotify(int32_t msg_type,
-        int32_t ext1,
-        int32_t ext2,
-        int32_t ext3) {
-    Mutex::Autolock l(mMutex);
-    mNotifications.push_back(Notification(msg_type, ext1, ext2, ext3));
-    mNewNotification.signal();
-}
-
-void NotifierListener::notify_callback_dispatch(int32_t msg_type,
-        int32_t ext1,
-        int32_t ext2,
-        int32_t ext3,
-        void *user) {
-    NotifierListener *me = reinterpret_cast<NotifierListener*>(user);
-    me->onNotify(msg_type, ext1, ext2, ext3);
-}
-
-/**
- * StreamAdapter
- */
-
-#ifndef container_of
-#define container_of(ptr, type, member) \
-    (type *)((char*)(ptr) - offsetof(type, member))
-#endif
-
-StreamAdapter::StreamAdapter(sp<IGraphicBufferProducer> consumer):
-        mState(UNINITIALIZED), mDevice(NULL),
-        mId(-1),
-        mWidth(0), mHeight(0), mFormat(0)
-{
-    mConsumerInterface = new Surface(consumer);
-    camera2_stream_ops::dequeue_buffer = dequeue_buffer;
-    camera2_stream_ops::enqueue_buffer = enqueue_buffer;
-    camera2_stream_ops::cancel_buffer = cancel_buffer;
-    camera2_stream_ops::set_crop = set_crop;
-}
-
-StreamAdapter::~StreamAdapter() {
-    disconnect();
-}
-
-status_t StreamAdapter::connectToDevice(camera2_device_t *d,
-        uint32_t width, uint32_t height, int format) {
-    if (mState != UNINITIALIZED) return INVALID_OPERATION;
-    if (d == NULL) {
-        ALOGE("%s: Null device passed to stream adapter", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    status_t res;
-
-    mWidth = width;
-    mHeight = height;
-    mFormat = format;
-
-    // Allocate device-side stream interface
-
-    uint32_t id;
-    uint32_t formatActual; // ignored
-    uint32_t usage;
-    uint32_t maxBuffers = 2;
-    res = d->ops->allocate_stream(d,
-            mWidth, mHeight, mFormat, getStreamOps(),
-            &id, &formatActual, &usage, &maxBuffers);
-    if (res != OK) {
-        ALOGE("%s: Device stream allocation failed: %s (%d)",
-                __FUNCTION__, strerror(-res), res);
-        mState = UNINITIALIZED;
-        return res;
-    }
-    mDevice = d;
-
-    mId = id;
-    mUsage = usage;
-    mMaxProducerBuffers = maxBuffers;
-
-    // Configure consumer-side ANativeWindow interface
-
-    res = native_window_api_connect(mConsumerInterface.get(),
-            NATIVE_WINDOW_API_CAMERA);
-    if (res != OK) {
-        ALOGE("%s: Unable to connect to native window for stream %d",
-                __FUNCTION__, mId);
-        mState = ALLOCATED;
-        return res;
-    }
-
-    res = native_window_set_usage(mConsumerInterface.get(), mUsage);
-    if (res != OK) {
-        ALOGE("%s: Unable to configure usage %08x for stream %d",
-                __FUNCTION__, mUsage, mId);
-        mState = CONNECTED;
-        return res;
-    }
-
-    res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
-            mWidth, mHeight);
-    if (res != OK) {
-        ALOGE("%s: Unable to configure buffer dimensions"
-                " %d x %d for stream %d",
-                __FUNCTION__, mWidth, mHeight, mId);
-        mState = CONNECTED;
-        return res;
-    }
-    res = native_window_set_buffers_format(mConsumerInterface.get(),
-            mFormat);
-    if (res != OK) {
-        ALOGE("%s: Unable to configure buffer format"
-                " 0x%x for stream %d",
-                __FUNCTION__, mFormat, mId);
-        mState = CONNECTED;
-        return res;
-    }
-
-    int maxConsumerBuffers;
-    res = mConsumerInterface->query(mConsumerInterface.get(),
-            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
-    if (res != OK) {
-        ALOGE("%s: Unable to query consumer undequeued"
-                " buffer count for stream %d", __FUNCTION__, mId);
-        mState = CONNECTED;
-        return res;
-    }
-    mMaxConsumerBuffers = maxConsumerBuffers;
-
-    ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__,
-            mMaxProducerBuffers, mMaxConsumerBuffers);
-
-    int totalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
-
-    res = native_window_set_buffer_count(mConsumerInterface.get(),
-            totalBuffers);
-    if (res != OK) {
-        ALOGE("%s: Unable to set buffer count for stream %d",
-                __FUNCTION__, mId);
-        mState = CONNECTED;
-        return res;
-    }
-
-    // Register allocated buffers with HAL device
-    buffer_handle_t *buffers = new buffer_handle_t[totalBuffers];
-    ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[totalBuffers];
-    int bufferIdx = 0;
-    for (; bufferIdx < totalBuffers; bufferIdx++) {
-        res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
-                &anwBuffers[bufferIdx]);
-        if (res != OK) {
-            ALOGE("%s: Unable to dequeue buffer %d for initial registration for"
-                    "stream %d", __FUNCTION__, bufferIdx, mId);
-            mState = CONNECTED;
-            goto cleanUpBuffers;
-        }
-        buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
-    }
-
-    res = mDevice->ops->register_stream_buffers(mDevice,
-            mId,
-            totalBuffers,
-            buffers);
-    if (res != OK) {
-        ALOGE("%s: Unable to register buffers with HAL device for stream %d",
-                __FUNCTION__, mId);
-        mState = CONNECTED;
-    } else {
-        mState = ACTIVE;
-    }
-
-cleanUpBuffers:
-    for (int i = 0; i < bufferIdx; i++) {
-        res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
-                anwBuffers[i], -1);
-    }
-    delete[] anwBuffers;
-    delete[] buffers;
-
-    return res;
-}
-
-status_t StreamAdapter::disconnect() {
-    status_t res;
-    if (mState >= ALLOCATED) {
-        res = mDevice->ops->release_stream(mDevice, mId);
-        if (res != OK) {
-            ALOGE("%s: Unable to release stream %d",
-                    __FUNCTION__, mId);
-            return res;
-        }
-    }
-    if (mState >= CONNECTED) {
-        res = native_window_api_disconnect(mConsumerInterface.get(),
-                NATIVE_WINDOW_API_CAMERA);
-        if (res != OK) {
-            ALOGE("%s: Unable to disconnect stream %d from native window",
-                    __FUNCTION__, mId);
-            return res;
-        }
-    }
-    mId = -1;
-    mState = DISCONNECTED;
-    return OK;
-}
-
-int StreamAdapter::getId() {
-    return mId;
-}
-
-const camera2_stream_ops *StreamAdapter::getStreamOps() {
-    return static_cast<camera2_stream_ops *>(this);
-}
-
-ANativeWindow* StreamAdapter::toANW(const camera2_stream_ops_t *w) {
-    return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
-}
-
-int StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
-        buffer_handle_t** buffer) {
-    int res;
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-
-    ANativeWindow *a = toANW(w);
-    ANativeWindowBuffer* anb;
-    res = native_window_dequeue_buffer_and_wait(a, &anb);
-    if (res != OK) return res;
-
-    *buffer = &(anb->handle);
-
-    return res;
-}
-
-int StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
-        int64_t timestamp,
-        buffer_handle_t* buffer) {
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-    ANativeWindow *a = toANW(w);
-    status_t err;
-    err = native_window_set_buffers_timestamp(a, timestamp);
-    if (err != OK) return err;
-    return a->queueBuffer(a,
-            container_of(buffer, ANativeWindowBuffer, handle), -1);
-}
-
-int StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
-        buffer_handle_t* buffer) {
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-    ANativeWindow *a = toANW(w);
-    return a->cancelBuffer(a,
-            container_of(buffer, ANativeWindowBuffer, handle), -1);
-}
-
-int StreamAdapter::set_crop(const camera2_stream_ops_t* w,
-        int left, int top, int right, int bottom) {
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-    ANativeWindow *a = toANW(w);
-    android_native_rect_t crop = { left, top, right, bottom };
-    return native_window_set_crop(a, &crop);
-}
-
-/**
- * FrameWaiter
- */
-
-FrameWaiter::FrameWaiter():
-        mPendingFrames(0) {
-}
-
-status_t FrameWaiter::waitForFrame(nsecs_t timeout) {
-    status_t res;
-    Mutex::Autolock lock(mMutex);
-    while (mPendingFrames == 0) {
-        res = mCondition.waitRelative(mMutex, timeout);
-        if (res != OK) return res;
-    }
-    mPendingFrames--;
-    return OK;
-}
-
-void FrameWaiter::onFrameAvailable(const BufferItem& /* item */) {
-    Mutex::Autolock lock(mMutex);
-    mPendingFrames++;
-    mCondition.signal();
-}
-
-int HWModuleHelpers::closeModule(void *dso) {
-    int status;
-    if (!dso) {
-        return -EINVAL;
-    }
-
-    status = dlclose(dso);
-    if (status != 0) {
-        char const *err_str = dlerror();
-        ALOGE("%s dlclose failed, error: %s", __func__, err_str ?: "unknown");
-    }
-
-    return status;
-}
-
-} // namespace tests
-} // namespace camera2
-} // namespace android
diff --git a/tests/camera2/camera2_utils.h b/tests/camera2/camera2_utils.h
deleted file mode 100644
index 274ee76..0000000
--- a/tests/camera2/camera2_utils.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __ANDROID_HAL_CAMERA2_TESTS_UTILS__
-#define __ANDROID_HAL_CAMERA2_TESTS_UTILS__
-
-// Utility classes for camera2 HAL testing
-
-#include <system/camera_metadata.h>
-#include <hardware/camera2.h>
-
-#include <gui/Surface.h>
-#include <gui/CpuConsumer.h>
-
-#include <utils/List.h>
-#include <utils/Mutex.h>
-#include <utils/Condition.h>
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-/**
- * Queue class for both sending requests to a camera2 device, and for receiving
- * frames from a camera2 device.
- */
-class MetadataQueue: public camera2_request_queue_src_ops_t,
-                    public camera2_frame_queue_dst_ops_t {
-  public:
-    MetadataQueue();
-    ~MetadataQueue();
-
-    // Interface to camera2 HAL device, either for requests (device is consumer)
-    // or for frames (device is producer)
-    const camera2_request_queue_src_ops_t*   getToConsumerInterface();
-    void setFromConsumerInterface(camera2_device_t *d);
-
-    const camera2_frame_queue_dst_ops_t* getToProducerInterface();
-
-    // Real interfaces. On enqueue, queue takes ownership of buffer pointer
-    // On dequeue, user takes ownership of buffer pointer.
-    status_t enqueue(camera_metadata_t *buf);
-    status_t dequeue(camera_metadata_t **buf, bool incrementCount = true);
-    int      getBufferCount();
-    status_t waitForBuffer(nsecs_t timeout);
-
-    // Set repeating buffer(s); if the queue is empty on a dequeue call, the
-    // queue copies the contents of the stream slot into the queue, and then
-    // dequeues the first new entry.
-    status_t setStreamSlot(camera_metadata_t *buf);
-    status_t setStreamSlot(const List<camera_metadata_t*> &bufs);
-
-  private:
-    status_t freeBuffers(List<camera_metadata_t*>::iterator start,
-                         const List<camera_metadata_t*>::iterator& end);
-
-    camera2_device_t *mDevice;
-
-    Mutex mMutex;
-    Condition notEmpty;
-
-    int mFrameCount;
-
-    int mCount;
-    List<camera_metadata_t*> mEntries;
-    int mStreamSlotCount;
-    List<camera_metadata_t*> mStreamSlot;
-
-    bool mSignalConsumer;
-
-    static MetadataQueue* getInstance(const camera2_frame_queue_dst_ops_t *q);
-    static MetadataQueue* getInstance(const camera2_request_queue_src_ops_t *q);
-
-    static int consumer_buffer_count(const camera2_request_queue_src_ops_t *q);
-
-    static int consumer_dequeue(const camera2_request_queue_src_ops_t *q,
-            camera_metadata_t **buffer);
-
-    static int consumer_free(const camera2_request_queue_src_ops_t *q,
-            camera_metadata_t *old_buffer);
-
-    static int producer_dequeue(const camera2_frame_queue_dst_ops_t *q,
-            size_t entries, size_t bytes,
-            camera_metadata_t **buffer);
-
-    static int producer_cancel(const camera2_frame_queue_dst_ops_t *q,
-            camera_metadata_t *old_buffer);
-
-    static int producer_enqueue(const camera2_frame_queue_dst_ops_t *q,
-            camera_metadata_t *filled_buffer);
-
-};
-
-/**
- * Basic class to receive and queue up notifications from the camera device
- */
-
-class NotifierListener {
-  public:
-
-    NotifierListener();
-
-    status_t getNotificationsFrom(camera2_device *dev);
-
-    status_t getNextNotification(int32_t *msg_type, int32_t *ext1,
-            int32_t *ext2, int32_t *ext3);
-
-    status_t waitForNotification(int32_t *msg_type, int32_t *ext1,
-            int32_t *ext2, int32_t *ext3);
-
-    int numNotifications();
-
-  private:
-
-    status_t getNextNotificationLocked(int32_t *msg_type,
-            int32_t *ext1, int32_t *ext2, int32_t *ext3);
-
-    struct Notification {
-        Notification(int32_t type, int32_t e1, int32_t e2, int32_t e3):
-                msg_type(type),
-                ext1(e1),
-                ext2(e2),
-                ext3(e3)
-        {}
-
-        int32_t msg_type;
-        int32_t ext1;
-        int32_t ext2;
-        int32_t ext3;
-    };
-
-    List<Notification> mNotifications;
-
-    Mutex mMutex;
-    Condition mNewNotification;
-
-    void onNotify(int32_t msg_type,
-            int32_t ext1,
-            int32_t ext2,
-            int32_t ext3);
-
-    static void notify_callback_dispatch(int32_t msg_type,
-            int32_t ext1,
-            int32_t ext2,
-            int32_t ext3,
-            void *user);
-
-};
-
-/**
- * Adapter from an IGraphicBufferProducer interface to camera2 device stream ops.
- * Also takes care of allocating/deallocating stream in device interface
- */
-class StreamAdapter: public camera2_stream_ops {
-  public:
-    explicit StreamAdapter(sp<IGraphicBufferProducer> consumer);
-
-    ~StreamAdapter();
-
-    status_t connectToDevice(camera2_device_t *d,
-            uint32_t width, uint32_t height, int format);
-
-    status_t disconnect();
-
-    // Get stream ID. Only valid after a successful connectToDevice call.
-    int      getId();
-
-  private:
-    enum {
-        ERROR = -1,
-        DISCONNECTED = 0,
-        UNINITIALIZED,
-        ALLOCATED,
-        CONNECTED,
-        ACTIVE
-    } mState;
-
-    sp<ANativeWindow> mConsumerInterface;
-    camera2_device_t *mDevice;
-
-    uint32_t mId;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mFormat;
-    uint32_t mUsage;
-    uint32_t mMaxProducerBuffers;
-    uint32_t mMaxConsumerBuffers;
-
-    const camera2_stream_ops *getStreamOps();
-
-    static ANativeWindow* toANW(const camera2_stream_ops_t *w);
-
-    static int dequeue_buffer(const camera2_stream_ops_t *w,
-            buffer_handle_t** buffer);
-
-    static int enqueue_buffer(const camera2_stream_ops_t* w,
-            int64_t timestamp,
-            buffer_handle_t* buffer);
-
-    static int cancel_buffer(const camera2_stream_ops_t* w,
-            buffer_handle_t* buffer);
-
-    static int set_crop(const camera2_stream_ops_t* w,
-            int left, int top, int right, int bottom);
-
-};
-
-/**
- * Simple class to wait on the CpuConsumer to have a frame available
- */
-class FrameWaiter : public CpuConsumer::FrameAvailableListener {
-  public:
-    FrameWaiter();
-
-    /**
-     * Wait for max timeout nanoseconds for a new frame. Returns
-     * OK if a frame is available, TIMED_OUT if the timeout was reached.
-     */
-    status_t waitForFrame(nsecs_t timeout);
-
-    virtual void onFrameAvailable(const BufferItem& item);
-
-    int mPendingFrames;
-    Mutex mMutex;
-    Condition mCondition;
-};
-
-struct HWModuleHelpers {
-    /* attempt to unload the library with dlclose */
-    static int closeModule(void* dso);
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/main.cpp b/tests/camera2/main.cpp
deleted file mode 100644
index e0ebbe9..0000000
--- a/tests/camera2/main.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-
-#include <gtest/gtest.h>
-#include "TestForkerEventListener.h"
-#include "TestSettings.h"
-
-using android::camera2::tests::TestForkerEventListener;
-using android::camera2::tests::TestSettings;
-
-int main(int argc, char **argv) {
-
-    bool printUsage = !TestSettings::ParseArgs(argc, argv);
-
-    ::testing::InitGoogleTest(&argc, argv);
-
-    if (printUsage) {
-        TestSettings::PrintUsage();
-        return 0;
-    }
-
-    // Gets hold of the event listener list.
-    ::testing::TestEventListeners& listeners =
-        ::testing::UnitTest::GetInstance()->listeners();
-    // Adds a listener to the end.  Google Test takes the ownership.
-    listeners.Append(new TestForkerEventListener());
-
-    int ret = RUN_ALL_TESTS();
-
-    return ret;
-}
diff --git a/tests/hardware/Android.bp b/tests/hardware/Android.bp
deleted file mode 100644
index 668e28f..0000000
--- a/tests/hardware/Android.bp
+++ /dev/null
@@ -1,15 +0,0 @@
-cc_library_static {
-    name: "static-hal-check",
-    srcs: [
-        "struct-size.cpp",
-        "struct-offset.cpp",
-        "struct-last.cpp",
-    ],
-    shared_libs: ["libhardware"],
-    cflags: [
-        "-std=gnu++11",
-        "-O0",
-    ],
-
-    include_dirs: ["system/media/camera/include"],
-}
diff --git a/tests/hardware/Android.mk b/tests/hardware/Android.mk
new file mode 100644
index 0000000..02540c9
--- /dev/null
+++ b/tests/hardware/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := static-hal-check
+LOCAL_SRC_FILES := struct-size.cpp struct-offset.cpp struct-last.cpp
+LOCAL_SHARED_LIBRARIES := libhardware
+LOCAL_CFLAGS := -std=gnu++11 -O0
+
+LOCAL_C_INCLUDES += \
+    system/media/camera/include
+
+include $(BUILD_STATIC_LIBRARY)
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/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