diff --git a/modules/sensors/dynamic_sensor/Android.mk b/modules/sensors/dynamic_sensor/Android.mk
index cdc1929..4608508 100644
--- a/modules/sensors/dynamic_sensor/Android.mk
+++ b/modules/sensors/dynamic_sensor/Android.mk
@@ -15,6 +15,24 @@
 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
@@ -25,7 +43,6 @@
 #
 # Please take only one of these two options to avoid conflict over hardware resource.
 #
-
 #
 # Option 1: sensor extension module
 #
@@ -37,18 +54,9 @@
 
 LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorExt\"
 
-LOCAL_SRC_FILES := \
-    BaseDynamicSensorDaemon.cpp \
-    BaseSensorObject.cpp \
-    ConnectionDetector.cpp \
-    DummyDynamicAccelDaemon.cpp \
-    DynamicSensorManager.cpp \
-    RingBuffer.cpp
+LOCAL_SRC_FILES := $(dynamic_sensor_src)
 
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog
+LOCAL_SHARED_LIBRARIES := $(dynamic_sensor_shared_lib)
 
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
 
@@ -66,23 +74,53 @@
 
 LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorHal\"
 
-LOCAL_SRC_FILES := \
-    BaseDynamicSensorDaemon.cpp \
-    BaseSensorObject.cpp \
-    ConnectionDetector.cpp \
-    DummyDynamicAccelDaemon.cpp \
-    DynamicSensorManager.cpp \
-    RingBuffer.cpp \
-    sensors.cpp
+LOCAL_SRC_FILES := $(dynamic_sensor_src) sensors.cpp
 
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog
+LOCAL_SHARED_LIBRARIES := $(dynamic_sensor_shared_lib)
 
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
 
 include $(BUILD_SHARED_LIBRARY)
 
-include $(LOCAL_PATH)/HidUtils/Android.mk
+#
+# Host test for HidRawSensor. Test with dummy test HID descriptors.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidrawsensor_host_test
+LOCAL_MODULE_TAGS := optional
 
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+
+LOCAL_SRC_FILES := \
+    HidRawSensor.cpp \
+    BaseSensorObject.cpp \
+    HidUtils/test/TestHidDescriptor.cpp \
+    test/HidRawSensorTest.cpp
+
+LOCAL_SHARED_LIBRARIES := libhidparser_host
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test $(LOCAL_PATH)/HidUtils/test
+include $(BUILD_HOST_EXECUTABLE)
+
+#
+# Host test for HidRawDevice and HidRawSensor. Test with hidraw
+# device node.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidrawdevice_host_test
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+
+LOCAL_SRC_FILES := \
+    HidRawDevice.cpp \
+    HidRawSensor.cpp \
+    BaseSensorObject.cpp \
+    test/HidRawDeviceTest.cpp
+
+LOCAL_SHARED_LIBRARIES := libhidparser_host
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test $(LOCAL_PATH)/HidUtils/test
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(LOCAL_PATH)/HidUtils/Android.mk
diff --git a/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.cpp b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.cpp
index f5f642c..7e9f217 100644
--- a/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.cpp
+++ b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.cpp
@@ -23,14 +23,23 @@
 
 bool BaseDynamicSensorDaemon::onConnectionChange(const std::string &deviceKey, bool connected) {
     bool ret = false;
-    auto i = mDevices.find(deviceKey);
+    auto i = mDeviceKeySensorMap.find(deviceKey);
     if (connected) {
-        if (i == mDevices.end()) {
+        if (i == mDeviceKeySensorMap.end()) {
             ALOGV("device %s is connected", deviceKey.c_str());
-            BaseSensorObject* s = createSensor(deviceKey);
-            if (s) {
-                mDevices.emplace(deviceKey, sp<BaseSensorObject>(s));
-                mManager.registerSensor(s);
+            // 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;
             }
@@ -39,13 +48,18 @@
         }
     } else {
         ALOGV("device %s is disconnected", deviceKey.c_str());
-        if (i != mDevices.end()) {
-            mManager.unregisterSensor(i->second.get());
-            mDevices.erase(i);
+        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 {
-            ALOGD("device not found in registry");
+            ALOGV("device not found in registry");
         }
     }
 
diff --git a/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h
index b698b7d..0cec965 100644
--- a/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h
+++ b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h
@@ -28,6 +28,8 @@
 
 class DynamicSensorManager;
 
+typedef std::vector<sp<BaseSensorObject>> BaseSensorVector;
+
 class BaseDynamicSensorDaemon : public RefBase {
 public:
     BaseDynamicSensorDaemon(DynamicSensorManager& manager) : mManager(manager) {}
@@ -35,10 +37,11 @@
 
     virtual bool onConnectionChange(const std::string &deviceKey, bool connected);
 protected:
-    virtual BaseSensorObject * createSensor(const std::string &deviceKey) = 0;
+    virtual BaseSensorVector createSensor(const std::string &deviceKey) = 0;
+    virtual void removeSensor(const std::string &/*deviceKey*/) {};
 
     DynamicSensorManager &mManager;
-    std::unordered_map<std::string, sp<BaseSensorObject> > mDevices;
+    std::unordered_map<std::string, BaseSensorVector> mDeviceKeySensorMap;
 };
 
 } // namespace SensorHalExt
diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
index 189e87f..4ec76b2 100644
--- a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
+++ b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
@@ -16,8 +16,8 @@
 
 #include "BaseSensorObject.h"
 #include "SensorEventCallback.h"
+#include "Utils.h"
 
-#include <utils/Log.h>
 #include <cstring>
 
 namespace android {
@@ -28,7 +28,6 @@
 
 bool BaseSensorObject::setEventCallback(SensorEventCallback* callback) {
     if (mCallback != nullptr) {
-        ALOGE("callback is already assigned, cannot change.");
         return false;
     }
     mCallback = callback;
@@ -51,7 +50,7 @@
 
 void BaseSensorObject::generateEvent(const sensors_event_t &e) {
     if (mCallback) {
-        mCallback->submitEvent(this, e);
+        mCallback->submitEvent(SP_THIS, e);
     }
 }
 
diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.h b/modules/sensors/dynamic_sensor/BaseSensorObject.h
index 326e138..e8d1a5d 100644
--- a/modules/sensors/dynamic_sensor/BaseSensorObject.h
+++ b/modules/sensors/dynamic_sensor/BaseSensorObject.h
@@ -17,8 +17,7 @@
 #ifndef ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
 #define ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
 
-#include <utils/RefBase.h>
-#include <utils/Timers.h> // for nsecs_t
+#include "Utils.h"
 #include <cstdint>
 
 struct sensor_t;
@@ -29,7 +28,7 @@
 
 class SensorEventCallback;
 
-class BaseSensorObject : virtual public RefBase {
+class BaseSensorObject : virtual public REF_BASE(BaseSensorObject) {
 public:
     BaseSensorObject();
     virtual ~BaseSensorObject() = default;
@@ -48,7 +47,8 @@
     virtual int enable(bool enable) = 0;
 
     // set sample period and batching period of sensor.
-    virtual int batch(nsecs_t samplePeriod, nsecs_t batchPeriod) = 0;
+    // 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();
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
index 6099493..67a6f27 100644
--- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
@@ -31,7 +31,7 @@
 
 // SocketConnectionDetector functions
 SocketConnectionDetector::SocketConnectionDetector(BaseDynamicSensorDaemon *d, int port)
-        : ConnectionDetector(d) {
+        : ConnectionDetector(d), Thread(false /*canCallJava*/) {
     // initialize socket that accept connection to localhost:port
     mListenFd = ::socket(AF_INET, SOCK_STREAM, 0);
     if (mListenFd < 0) {
@@ -105,7 +105,7 @@
 // FileConnectionDetector functions
 FileConnectionDetector::FileConnectionDetector (
         BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex)
-            : ConnectionDetector(d), mPath(path), mRegex(regex) {
+            : ConnectionDetector(d), Thread(false /*callCallJava*/), mPath(path), mRegex(regex) {
     mInotifyFd = ::inotify_init1(IN_NONBLOCK);
     if (mInotifyFd < 0) {
         ALOGE("Cannot init inotify");
diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
index 1977967..a1a47e8 100644
--- a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
+++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp
@@ -51,23 +51,30 @@
     }
 }
 
-BaseSensorObject * DummyDynamicAccelDaemon::createSensor(const std::string &deviceKey) {
+BaseSensorVector DummyDynamicAccelDaemon::createSensor(const std::string &deviceKey) {
+    BaseSensorVector ret;
     if (deviceKey.compare(0, 1, "/") == 0) {
         // file detector result, deviceKey is file absolute path
-        size_t start = std::max(static_cast<size_t>(0),
-                                deviceKey.length() - (::strlen(FILE_NAME_BASE) + 1));
-        return new DummySensor(deviceKey.substr(start));
-
+        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) {
-        return new DummySensor(deviceKey);
+        ret.emplace_back(new DummySensor(deviceKey));
     } else {
         // unknown deviceKey
-        return nullptr;
+        ALOGE("unknown deviceKey: %s", deviceKey.c_str());
     }
+    return ret;
 }
 
-DummyDynamicAccelDaemon::DummySensor::DummySensor(const std::string &name) : mRunState(false) {
+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.",
@@ -120,7 +127,8 @@
     return 0;
 }
 
-int DummyDynamicAccelDaemon::DummySensor::batch(nsecs_t, nsecs_t) {
+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;
 }
 
diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.h b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.h
index 0bffbee..95a5730 100644
--- a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.h
+++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.h
@@ -61,7 +61,7 @@
         bool mRunState;
     };
     // implement BaseDynamicSensorDaemon function
-    BaseSensorObject * createSensor(const std::string &deviceKey) override;
+    virtual BaseSensorVector createSensor(const std::string &deviceKey) override;
 
     sp<ConnectionDetector> mFileDetector;
     sp<ConnectionDetector> mSocketDetector;
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
index eb4903d..b634052 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
@@ -17,6 +17,7 @@
 #include "BaseDynamicSensorDaemon.h"
 #include "BaseSensorObject.h"
 #include "DummyDynamicAccelDaemon.h"
+#include "HidRawSensorDaemon.h"
 #include "DynamicSensorManager.h"
 
 #include <utils/Log.h>
@@ -31,6 +32,7 @@
         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;
 }
 
@@ -107,7 +109,7 @@
 
 int DynamicSensorManager::flush(int handle) {
     if (handle == mHandleRange.first) {
-        // TODO: submit a flush complete here
+        // submit a flush complete here
         static const sensors_event_t event = {
             .type = SENSOR_TYPE_META_DATA,
             .sensor = mHandleRange.first,
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
index b8fd472..b6f39da 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
@@ -123,7 +123,7 @@
     // mapping between handle and SensorObjects
     mutable std::mutex mLock;
     int mNextHandle;
-    std::unordered_map<int, wp<BaseSensorObject> > mMap;
+    std::unordered_map<int, wp<BaseSensorObject>> mMap;
     std::unordered_map<void *, int> mReverseMap;
     mutable std::unordered_map<int, ConnectionReport> mPendingReport;
 
diff --git a/modules/sensors/dynamic_sensor/HidDevice.h b/modules/sensors/dynamic_sensor/HidDevice.h
new file mode 100644
index 0000000..7083593
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidDevice.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_HID_DEVICE_H
+#define ANDROID_SENSORHAL_EXT_HID_DEVICE_H
+#include "Utils.h"
+#include <string>
+#include <vector>
+#include <unordered_set>
+
+namespace android {
+namespace SensorHalExt {
+
+class HidDevice : virtual public REF_BASE(HidDevice) {
+public:
+    virtual ~HidDevice() = default;
+
+    struct HidDeviceInfo {
+        std::string name;
+        std::string physicalPath;
+        std::string busType;
+        uint16_t vendorId;
+        uint16_t productId;
+        std::vector<uint8_t> descriptor;
+    };
+
+    virtual const HidDeviceInfo& getDeviceInfo() = 0;
+
+    // get feature from device
+    virtual bool getFeature(uint8_t id, std::vector<uint8_t> *out) = 0;
+
+    // write feature to device
+    virtual bool setFeature(uint8_t id, const std::vector<uint8_t> &in) = 0;
+
+    // send report to default output endpoint
+    virtual bool sendReport(uint8_t id, std::vector<uint8_t> &data) = 0;
+
+    // receive from default input endpoint
+    virtual bool receiveReport(uint8_t *id, std::vector<uint8_t> *data) = 0;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+#endif // ANDROID_SENSORHAL_EXT_HID_DEVICE_H
diff --git a/modules/sensors/dynamic_sensor/HidRawDevice.cpp b/modules/sensors/dynamic_sensor/HidRawDevice.cpp
new file mode 100644
index 0000000..2588483
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawDevice.cpp
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidRawDevice.h"
+#include "HidLog.h"
+#include "Utils.h"
+
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+#include <linux/hiddev.h>  // HID_STRING_SIZE
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <set>
+
+namespace android {
+namespace SensorHalExt {
+
+using HidUtil::HidItem;
+
+HidRawDevice::HidRawDevice(
+        const std::string &devName, const std::unordered_set<unsigned int> &usageSet)
+        : mDevFd(-1), mMultiIdDevice(false), mValid(false) {
+    // open device
+    mDevFd = ::open(devName.c_str(), O_RDWR); // read write?
+    if (mDevFd < 0) {
+        LOG_E << "Error in open device node: " << errno << " (" << ::strerror(errno) << ")"
+              << LOG_ENDL;
+        return;
+    }
+
+    // get device information, including hid descriptor
+    if (!populateDeviceInfo()) {
+        LOG_E << "Error obtaining HidRaw device information" << LOG_ENDL;
+        return;
+    }
+
+    if (!generateDigest(usageSet)) {
+        LOG_E << "Cannot parse hid descriptor" << LOG_ENDL;
+        return;
+    }
+
+    // digest error checking
+    std::unordered_set<unsigned int> reportIdSet;
+    for (auto const &digest : mDigestVector) {
+        for (auto const &packet : digest.packets) {
+            if (mReportTypeIdMap.emplace(
+                        std::make_pair(packet.type, packet.id), &packet).second == false) {
+                LOG_E << "Same type - report id pair (" << packet.type << ", " << packet.id << ")"
+                      << "is used by more than one usage collection" << LOG_ENDL;
+                return;
+            }
+            reportIdSet.insert(packet.id);
+        }
+    }
+    if (mReportTypeIdMap.empty()) {
+        return;
+    }
+
+    if (reportIdSet.size() > 1) {
+        if (reportIdSet.find(0) != reportIdSet.end()) {
+            LOG_E << "Default report id 0 is not expected when more than one report id is found."
+                  << LOG_ENDL;
+            return;
+        }
+        mMultiIdDevice = true;
+    } else { // reportIdSet.size() == 1
+        mMultiIdDevice = !(reportIdSet.find(0) != reportIdSet.end());
+    }
+    mValid = true;
+}
+
+HidRawDevice::~HidRawDevice() {
+    if (mDevFd > 0) {
+        ::close(mDevFd);
+        mDevFd = -1;
+    }
+}
+
+bool HidRawDevice::populateDeviceInfo() {
+    HidDeviceInfo info;
+    char buffer[HID_STRING_SIZE + 1];
+
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    // name
+    if (ioctl(mDevFd, HIDIOCGRAWNAME(sizeof(buffer) - 1), buffer) < 0) {
+        return false;
+    }
+    buffer[sizeof(buffer) - 1] = '\0';
+    info.name = buffer;
+
+    // physical path
+    if (ioctl(mDevFd, HIDIOCGRAWPHYS(sizeof(buffer) - 1), buffer) < 0) {
+        return false;
+    }
+    buffer[sizeof(buffer) - 1] = '\0';
+    info.physicalPath = buffer;
+
+    // raw device info
+    hidraw_devinfo devInfo;
+    if (ioctl(mDevFd, HIDIOCGRAWINFO, &devInfo) < 0) {
+        return false;
+    }
+
+    switch (devInfo.bustype) {
+    case BUS_USB:
+        info.busType = "USB";
+        break;
+    case BUS_HIL:
+        info.busType = "HIL";
+        break;
+    case BUS_BLUETOOTH:
+        info.busType = "Bluetooth";
+        break;
+    case BUS_VIRTUAL:
+        info.busType = "Virtual";
+        break;
+    default:
+        info.busType = "Other";
+        break;
+    }
+
+    info.vendorId = devInfo.vendor;
+    info.productId = devInfo.vendor;
+
+    uint32_t descriptorSize;
+    /* Get Report Descriptor Size */
+    if (ioctl(mDevFd, HIDIOCGRDESCSIZE, &descriptorSize) < 0) {
+        return false;
+    }
+
+    struct hidraw_report_descriptor reportDescriptor;
+    memset(&reportDescriptor, 0, sizeof(reportDescriptor));
+    info.descriptor.resize(descriptorSize);
+    reportDescriptor.size = descriptorSize;
+    if (ioctl(mDevFd, HIDIOCGRDESC, &reportDescriptor) < 0) {
+        return false;
+    }
+    std::copy(reportDescriptor.value, reportDescriptor.value + descriptorSize,
+              info.descriptor.begin());
+    mDeviceInfo = info;
+    return true;
+}
+
+bool HidRawDevice::generateDigest(const std::unordered_set<unsigned int> &usage) {
+    if (mDeviceInfo.descriptor.empty()) {
+        return false;
+    }
+
+    std::vector<HidItem> tokens = HidItem::tokenize(mDeviceInfo.descriptor);
+    HidParser parser;
+    if (!parser.parse(tokens)) {
+        return false;
+    }
+
+    parser.filterTree();
+    mDigestVector = parser.generateDigest(usage);
+
+    return mDigestVector.size() > 0;
+}
+
+bool HidRawDevice::isValid() {
+    return mValid;
+}
+
+bool HidRawDevice::getFeature(uint8_t id, std::vector<uint8_t> *out) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    if (out == nullptr) {
+        return false;
+    }
+
+    const HidParser::ReportPacket *packet = getReportPacket(HidParser::REPORT_TYPE_FEATURE, id);
+    if (packet == nullptr) {
+        LOG_E << "HidRawDevice::getFeature: unknown feature " << id << LOG_ENDL;
+        return false;
+    }
+
+    size_t size = packet->getByteSize() + 1; // report id size
+
+    std::lock_guard<std::mutex> l(mIoBufferLock);
+    if (mIoBuffer.size() < size) {
+        mIoBuffer.resize(size);
+    }
+    mIoBuffer[0] = id;
+    int res = ::ioctl(mDevFd, HIDIOCGFEATURE(size), mIoBuffer.data());
+    if (res < 0) {
+        LOG_E << "HidRawDevice::getFeature: feature " << static_cast<int>(id)
+              << " ioctl returns " << res << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+
+    if (static_cast<size_t>(res) != size) {
+        LOG_E << "HidRawDevice::getFeature: get feature " << static_cast<int>(id)
+              << " returned " << res << " bytes, does not match expected " << size << LOG_ENDL;
+        return false;
+    }
+    if (mIoBuffer.front() != id) {
+        LOG_E << "HidRawDevice::getFeature: get feature " << static_cast<int>(id)
+              << " result has header " << mIoBuffer.front() << LOG_ENDL;
+    }
+    out->resize(size - 1);
+    std::copy(mIoBuffer.begin() + 1, mIoBuffer.begin() + size, out->begin());
+    return true;
+}
+
+bool HidRawDevice::setFeature(uint8_t id, const std::vector<uint8_t> &in) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    const HidParser::ReportPacket *packet = getReportPacket(HidParser::REPORT_TYPE_FEATURE, id);
+    if (packet == nullptr) {
+        LOG_E << "HidRawDevice::setFeature: Unknown feature " << id << LOG_ENDL;
+        return false;
+    }
+
+    size_t size = packet->getByteSize();
+    if (size != in.size()) {
+        LOG_E << "HidRawDevice::setFeature: set feature " << id << " size mismatch, need "
+              << size << " bytes, have " << in.size() << " bytes" << LOG_ENDL;
+        return false;
+    }
+
+    ++size; // report id byte
+    std::lock_guard<std::mutex> l(mIoBufferLock);
+    if (mIoBuffer.size() < size) {
+        mIoBuffer.resize(size);
+    }
+    mIoBuffer[0] = id;
+    std::copy(in.begin(), in.end(), &mIoBuffer[1]);
+    int res = ::ioctl(mDevFd, HIDIOCSFEATURE(size), mIoBuffer.data());
+    if (res < 0) {
+        LOG_E << "HidRawDevice::setFeature: feature " << id << " ioctl returns " << res
+              << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+    return true;
+}
+
+bool HidRawDevice::sendReport(uint8_t id, std::vector<uint8_t> &data) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    const HidParser::ReportPacket *packet = getReportPacket(HidParser::REPORT_TYPE_OUTPUT, id);
+    if (packet == nullptr) {
+        LOG_E << "HidRawDevice::sendReport: unknown output " << id << LOG_ENDL;
+        return false;
+    }
+
+    size_t size = packet->getByteSize();
+    if (size != data.size()) {
+        LOG_E << "HidRawDevice::sendReport: send report " << id << " size mismatch, need "
+              << size << " bytes, have " << data.size() << " bytes" << LOG_ENDL;
+        return false;
+    }
+    int res;
+    if (mMultiIdDevice) {
+        std::lock_guard<std::mutex> l(mIoBufferLock);
+        ++size;
+        if (mIoBuffer.size() < size) {
+            mIoBuffer.resize(size);
+        }
+        mIoBuffer[0] = id;
+        std::copy(mIoBuffer.begin() + 1, mIoBuffer.end(), data.begin());
+        res = ::write(mDevFd, mIoBuffer.data(), size);
+    } else {
+        res = ::write(mDevFd, data.data(), size);
+    }
+    if (res < 0) {
+        LOG_E << "HidRawDevice::sendReport: output " << id << " write returns " << res
+              << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+    return true;
+}
+
+bool HidRawDevice::receiveReport(uint8_t *id, std::vector<uint8_t> *data) {
+    if (mDevFd < 0) {
+        return false;
+    }
+
+    uint8_t buffer[256];
+    int res = ::read(mDevFd, buffer, 256);
+    if (res < 0) {
+        LOG_E << "HidRawDevice::receiveReport: read returns " << res
+              << " (" << ::strerror(res) << ")" << LOG_ENDL;
+        return false;
+    }
+
+    if (mMultiIdDevice) {
+        if (!(res > 1)) {
+            LOG_E << "read hidraw returns data too short, len: " << res << LOG_ENDL;
+            return false;
+        }
+        data->resize(static_cast<size_t>(res - 1));
+        std::copy(buffer + 1, buffer + res, data->begin());
+        *id = buffer[0];
+    } else {
+        data->resize(static_cast<size_t>(res));
+        std::copy(buffer, buffer + res, data->begin());
+        *id = 0;
+    }
+    return true;
+}
+
+const HidParser::ReportPacket *HidRawDevice::getReportPacket(unsigned int type, unsigned int id) {
+    auto i = mReportTypeIdMap.find(std::make_pair(type, id));
+    return (i == mReportTypeIdMap.end()) ? nullptr : i->second;
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/HidRawDevice.h b/modules/sensors/dynamic_sensor/HidRawDevice.h
new file mode 100644
index 0000000..707dfff
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawDevice.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+
+#include "HidDevice.h"
+
+#include <HidParser.h>
+#include <string>
+#include <vector>
+#include <unordered_set>
+#include <unordered_map>
+
+namespace android {
+namespace SensorHalExt {
+
+using HidUtil::HidParser;
+using HidUtil::HidReport;
+
+class HidRawDevice : public HidDevice {
+    friend class HidRawDeviceTest;
+public:
+    HidRawDevice(const std::string &devName, const std::unordered_set<unsigned int> &usageSet);
+    virtual ~HidRawDevice();
+
+    // test if the device initialized successfully
+    bool isValid();
+
+    // implement HidDevice pure virtuals
+    virtual HidDeviceInfo& getDeviceInfo() override { return mDeviceInfo; }
+    virtual bool getFeature(uint8_t id, std::vector<uint8_t> *out) override;
+    virtual bool setFeature(uint8_t id, const std::vector<uint8_t> &in) override;
+    virtual bool sendReport(uint8_t id, std::vector<uint8_t> &data) override;
+    virtual bool receiveReport(uint8_t *id, std::vector<uint8_t> *data) override;
+
+protected:
+    bool populateDeviceInfo();
+    size_t getReportSize(int type, uint8_t id);
+    bool generateDigest(const std::unordered_set<uint32_t> &usage);
+    size_t calculateReportBitSize(const std::vector<HidReport> &reportItems);
+    const HidParser::ReportPacket *getReportPacket(unsigned int type, unsigned int id);
+
+    typedef std::pair<unsigned int, unsigned int> ReportTypeIdPair;
+    struct UnsignedIntPairHash {
+        size_t operator()(const ReportTypeIdPair& v) const {
+            std::hash<unsigned int> hash;
+            return hash(v.first) ^ hash(v.second);
+        }
+    };
+
+    std::unordered_map<ReportTypeIdPair, const HidParser::ReportPacket *, UnsignedIntPairHash>
+            mReportTypeIdMap;
+
+    HidParser::DigestVector mDigestVector;
+private:
+    std::mutex mIoBufferLock;
+    std::vector<uint8_t> mIoBuffer;
+
+    int mDevFd;
+    HidDeviceInfo mDeviceInfo;
+    bool mMultiIdDevice;
+    int mValid;
+
+    HidRawDevice(const HidRawDevice &) = delete;
+    void operator=(const HidRawDevice &) = delete;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
new file mode 100644
index 0000000..a64d7a6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
@@ -0,0 +1,1044 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidRawSensor.h"
+#include "HidSensorDef.h"
+
+#include <utils/Errors.h>
+#include "HidLog.h"
+
+#include <algorithm>
+#include <cfloat>
+#include <codecvt>
+#include <iomanip>
+#include <sstream>
+
+namespace android {
+namespace SensorHalExt {
+
+namespace {
+const std::string CUSTOM_TYPE_PREFIX("com.google.hardware.sensor.hid_dynamic.");
+}
+
+HidRawSensor::HidRawSensor(
+        SP(HidDevice) device, uint32_t usage, const std::vector<HidParser::ReportPacket> &packets)
+        : mReportingStateId(-1), mPowerStateId(-1), mReportIntervalId(-1), mInputReportId(-1),
+        mEnabled(false), mSamplingPeriod(1000ll*1000*1000), mBatchingPeriod(0),
+        mDevice(device), mValid(false) {
+    if (device == nullptr) {
+        return;
+    }
+    memset(&mSensor, 0, sizeof(mSensor));
+
+    const HidDevice::HidDeviceInfo &info =  device->getDeviceInfo();
+    initFeatureValueFromHidDeviceInfo(&mFeatureInfo, info);
+
+    if (!populateFeatureValueFromFeatureReport(&mFeatureInfo, packets)) {
+        LOG_E << "populate feature from feature report failed" << LOG_ENDL;
+        return;
+    }
+
+    if (!findSensorControlUsage(packets)) {
+        LOG_E << "finding sensor control usage failed" << LOG_ENDL;
+        return;
+    }
+
+    // build translation table
+    bool translationTableValid = false;
+    switch (usage) {
+        using namespace Hid::Sensor::SensorTypeUsage;
+        using namespace Hid::Sensor::ReportUsage;
+        case ACCELEROMETER_3D:
+            // Hid unit default g
+            // Android unit m/s^2
+            // 1g = 9.81 m/s^2
+            mFeatureInfo.typeString = SENSOR_STRING_TYPE_ACCELEROMETER;
+            mFeatureInfo.type = SENSOR_TYPE_ACCELEROMETER;
+            mFeatureInfo.isWakeUp = false;
+
+            translationTableValid = processTriAxisUsage(packets,
+                                         ACCELERATION_X_AXIS,
+                                         ACCELERATION_Y_AXIS,
+                                         ACCELERATION_Z_AXIS, 9.81);
+            break;
+        case GYROMETER_3D:
+            // Hid unit default degree/s
+            // Android unit rad/s
+            // 1 degree/s = pi/180 rad/s
+            mFeatureInfo.typeString = SENSOR_STRING_TYPE_GYROSCOPE;
+            mFeatureInfo.type = SENSOR_TYPE_GYROSCOPE;
+            mFeatureInfo.isWakeUp = false;
+
+            translationTableValid = processTriAxisUsage(packets,
+                                         ANGULAR_VELOCITY_X_AXIS,
+                                         ANGULAR_VELOCITY_Y_AXIS,
+                                         ANGULAR_VELOCITY_Z_AXIS, M_PI/180);
+            break;
+        case COMPASS_3D: {
+            // Hid unit default mGauss
+            // Android unit uT
+            // 1uT  = 0.1 nGauss
+            mFeatureInfo.typeString = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
+            mFeatureInfo.type = SENSOR_TYPE_MAGNETIC_FIELD;
+
+            if (!processTriAxisUsage(packets,
+                                     MAGNETIC_FLUX_X_AXIS,
+                                     MAGNETIC_FLUX_Y_AXIS,
+                                     MAGNETIC_FLUX_Z_AXIS, 0.1)) {
+                break;
+            }
+            const HidParser::ReportItem *pReportAccuracy = find(packets,
+                                                                  MAGNETOMETER_ACCURACY,
+                                                                  HidParser::REPORT_TYPE_INPUT,
+                                                                  mInputReportId);
+
+            if (pReportAccuracy == nullptr) {
+                LOG_E << "Cannot find accuracy field in usage "
+                      << std::hex << usage << std::dec << LOG_ENDL;
+                break;
+            }
+            if (!pReportAccuracy->isByteAligned()) {
+                LOG_E << "Accuracy field must align to byte" << LOG_ENDL;
+                break;
+            }
+            if (pReportAccuracy->minRaw != 0 || pReportAccuracy->maxRaw != 2) {
+                LOG_E << "Accuracy field value range must be [0, 2]" << LOG_ENDL;
+                break;
+            }
+            ReportTranslateRecord accuracyRecord = {
+                .type = TYPE_ACCURACY,
+                .maxValue = 2,
+                .minValue = 0,
+                .byteOffset = pReportAccuracy->bitOffset / 8,
+                .byteSize = pReportAccuracy->bitSize / 8,
+                .a = 1,
+                .b = 1};
+            mTranslateTable.push_back(accuracyRecord);
+            translationTableValid = true;
+            break;
+        }
+        case DEVICE_ORIENTATION:
+            translationTableValid = processQuaternionUsage(packets);
+            break;
+        case CUSTOM: {
+            if (!mFeatureInfo.isAndroidCustom) {
+                LOG_E << "Invalid android custom sensor" << LOG_ENDL;
+                break;
+            }
+            const HidParser::ReportPacket *pPacket = nullptr;
+            const uint32_t usages[] = {
+                CUSTOM_VALUE_1, CUSTOM_VALUE_2, CUSTOM_VALUE_3,
+                CUSTOM_VALUE_4, CUSTOM_VALUE_5, CUSTOM_VALUE_6
+            };
+            for (const auto &packet : packets) {
+                if (packet.type == HidParser::REPORT_TYPE_INPUT && std::any_of(
+                        packet.reports.begin(), packet.reports.end(),
+                        [&usages] (const HidParser::ReportItem &d) {
+                               return std::find(std::begin(usages), std::end(usages), d.usage)
+                                       != std::end(usages);
+                        })) {
+                    pPacket = &packet;
+                    break;
+                }
+            }
+
+            if (pPacket == nullptr) {
+                LOG_E << "Cannot find CUSTOM_VALUE_X in custom sensor" << LOG_ENDL;
+                break;
+            }
+
+            double range = 0;
+            double resolution = 1;
+
+            for (const auto &digest : pPacket->reports) {
+                if (digest.minRaw >= digest.maxRaw) {
+                    LOG_E << "Custome usage " << digest.usage << ", min must < max" << LOG_ENDL;
+                    return;
+                }
+
+                if (!digest.isByteAligned()
+                        || (digest.bitSize != 8 && digest.bitSize != 16 && digest.bitSize != 32)) {
+                    LOG_E << "Custome usage " << std::hex << digest.usage << std::hex
+                          << ", each input must be 8/16/32 bits and must align to byte boundary"
+                          << LOG_ENDL;
+                    return;
+                }
+
+                ReportTranslateRecord record = {
+                    .minValue = digest.minRaw,
+                    .maxValue = digest.maxRaw,
+                    .byteOffset = digest.bitOffset / 8,
+                    .byteSize = digest.bitSize / 8,
+                    .a = digest.a,
+                    .b = digest.b,
+                    .type = TYPE_FLOAT
+                };
+                // keep track of range and resolution
+                range = std::max(std::max(std::abs((digest.maxRaw + digest.b) * digest.a),
+                                          std::abs((digest.minRaw + digest.b) * digest.a)),
+                                 range);
+                resolution = std::min(digest.a, resolution);
+
+                for (size_t i = 0; i < digest.count; ++i) {
+                    if (mTranslateTable.size() == 16) {
+                        LOG_I << "Custom usage has more than 16 inputs, ignore the rest" << LOG_ENDL;
+                        break;
+                    }
+                    record.index = mTranslateTable.size();
+                    mTranslateTable.push_back(record);
+                    record.byteOffset += digest.bitSize / 8;
+                }
+                if (mTranslateTable.size() == 16) {
+                    break;
+                }
+            }
+            mFeatureInfo.maxRange = range;
+            mFeatureInfo.resolution = resolution;
+            mInputReportId = pPacket->id;
+            translationTableValid = !mTranslateTable.empty();
+            break;
+        }
+        default:
+            LOG_I << "unsupported sensor usage " << usage << LOG_ENDL;
+    }
+
+    bool sensorValid = validateFeatureValueAndBuildSensor();
+    mValid = translationTableValid && sensorValid;
+    LOG_V << "HidRawSensor init, translationTableValid: " << translationTableValid
+          << ", sensorValid: " << sensorValid << LOG_ENDL;
+}
+
+bool HidRawSensor::processQuaternionUsage(const std::vector<HidParser::ReportPacket> &packets) {
+    const HidParser::ReportItem *pReportQuaternion
+            = find(packets,
+                   Hid::Sensor::ReportUsage::ORIENTATION_QUATERNION,
+                   HidParser::REPORT_TYPE_INPUT);
+
+    if (pReportQuaternion == nullptr) {
+        return false;
+    }
+
+    const HidParser::ReportItem &quat = *pReportQuaternion;
+    if ((quat.bitSize != 16 && quat.bitSize != 32) || !quat.isByteAligned()) {
+        LOG_E << "Quaternion usage input must be 16 or 32 bits and aligned at byte boundary" << LOG_ENDL;
+        return false;
+    }
+
+    double min, max;
+    quat.decode(quat.mask(quat.minRaw), &min);
+    quat.decode(quat.mask(quat.maxRaw), &max);
+    if (quat.count != 4 || min > -1 || max < 1) {
+        LOG_E << "Quaternion usage need 4 inputs with range [-1, 1]" << LOG_ENDL;
+        return false;
+    }
+
+    if (quat.minRaw > quat.maxRaw) {
+        LOG_E << "Quaternion usage min must <= max" << LOG_ENDL;
+        return false;
+    }
+
+    ReportTranslateRecord record = {
+        .minValue = quat.minRaw,
+        .maxValue = quat.maxRaw,
+        .byteOffset = quat.bitOffset / 8,
+        .byteSize = quat.bitSize / 8,
+        .b = quat.b,
+        .type = TYPE_FLOAT,
+    };
+
+    // Android X Y Z maps to HID X -Z Y
+    // Android order xyzw, HID order wxyz
+    // X
+    record.index = 0;
+    record.a = quat.a;
+    record.byteOffset = (quat.bitOffset + quat.bitSize) / 8;
+    mTranslateTable.push_back(record);
+    // Y
+    record.index = 1;
+    record.a = -quat.a;
+    record.byteOffset = (quat.bitOffset + 3 * quat.bitSize) / 8;
+    mTranslateTable.push_back(record);
+    // Z
+    record.index = 2;
+    record.a = quat.a;
+    record.byteOffset = (quat.bitOffset + 2 * quat.bitSize) / 8;
+    mTranslateTable.push_back(record);
+    // W
+    record.index = 3;
+    record.a = quat.a;
+    record.byteOffset = quat.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    mFeatureInfo.typeString = SENSOR_STRING_TYPE_ROTATION_VECTOR;
+    mFeatureInfo.type = SENSOR_TYPE_ROTATION_VECTOR;
+    mFeatureInfo.maxRange = 1;
+    mFeatureInfo.resolution = quat.a;
+    mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
+
+    mInputReportId = quat.id;
+
+    return true;
+}
+
+bool HidRawSensor::processTriAxisUsage(const std::vector<HidParser::ReportPacket> &packets,
+        uint32_t usageX, uint32_t usageY, uint32_t usageZ, double defaultScaling) {
+    const HidParser::ReportItem *pReportX = find(packets, usageX, HidParser::REPORT_TYPE_INPUT);
+    const HidParser::ReportItem *pReportY = find(packets, usageY, HidParser::REPORT_TYPE_INPUT);
+    const HidParser::ReportItem *pReportZ = find(packets, usageZ, HidParser::REPORT_TYPE_INPUT);
+
+    if (pReportX == nullptr || pReportY == nullptr|| pReportZ == nullptr) {
+        LOG_E << "Three axis sensor does not find all 3 axis" << LOG_ENDL;
+        return false;
+    }
+
+    const HidParser::ReportItem &reportX = *pReportX;
+    const HidParser::ReportItem &reportY = *pReportY;
+    const HidParser::ReportItem &reportZ = *pReportZ;
+    if (reportX.id != reportY.id || reportY.id != reportZ.id) {
+        LOG_E << "All 3 axis should be in the same report" << LOG_ENDL;
+        return false;
+    }
+    if (reportX.minRaw >= reportX.maxRaw
+            || reportX.minRaw != reportY.minRaw
+            || reportX.maxRaw != reportY.maxRaw
+            || reportY.minRaw != reportZ.minRaw
+            || reportY.maxRaw != reportZ.maxRaw) {
+        LOG_E << "All 3 axis should have same min and max value and min must < max" << LOG_ENDL;
+        return false;
+    }
+    if (reportX.a != reportY.a || reportY.a != reportY.a) {
+        LOG_E << "All 3 axis should have same resolution" << LOG_ENDL;
+        return false;
+    }
+    if (reportX.count != 1 || reportY.count != 1 || reportZ.count != 1
+            || (reportX.bitSize != 16 && reportX.bitSize != 32)
+            || reportX.bitSize != reportY.bitSize || reportY.bitSize != reportZ.bitSize
+            || !reportX.isByteAligned()
+            || !reportY.isByteAligned()
+            || !reportZ.isByteAligned() ) {
+        LOG_E << "All 3 axis should have count == 1, same size == 16 or 32 "
+              "and align at byte boundary" << LOG_ENDL;
+        return false;
+    }
+
+    if (reportX.unit != 0 || reportY.unit != 0 || reportZ.unit != 0) {
+        LOG_E << "Specified unit for usage is not supported" << LOG_ENDL;
+        return false;
+    }
+
+    if (reportX.a != reportY.a || reportY.a != reportZ.a
+        || reportX.b != reportY.b || reportY.b != reportZ.b) {
+        LOG_W << "Scaling for 3 axis are different. It is recommended to keep them the same" << LOG_ENDL;
+    }
+
+    // set features
+    mFeatureInfo.maxRange = std::max(
+        std::abs((reportX.maxRaw + reportX.b) * reportX.a),
+        std::abs((reportX.minRaw + reportX.b) * reportX.a));
+    mFeatureInfo.resolution = reportX.a * defaultScaling;
+    mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
+
+    ReportTranslateRecord record = {
+        .minValue = reportX.minRaw,
+        .maxValue = reportX.maxRaw,
+        .byteSize = reportX.bitSize / 8,
+        .type = TYPE_FLOAT
+    };
+
+    // Reorder and swap axis
+    //
+    // HID class devices are encouraged, where possible, to use a right-handed
+    // coordinate system. If a user is facing a device, report values should increase as
+    // controls are moved from left to right (X), from far to near (Y) and from high to
+    // low (Z).
+    //
+
+    // Android X axis = Hid X axis
+    record.index = 0;
+    record.a = reportX.a * defaultScaling;
+    record.b = reportX.b;
+    record.byteOffset = reportX.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    // Android Y axis = - Hid Z axis
+    record.index = 1;
+    record.a = -reportZ.a * defaultScaling;
+    record.b = reportZ.b;
+    record.byteOffset = reportZ.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    // Android Z axis = Hid Y axis
+    record.index = 2;
+    record.a = reportY.a * defaultScaling;
+    record.b = reportY.b;
+    record.byteOffset = reportY.bitOffset / 8;
+    mTranslateTable.push_back(record);
+
+    mInputReportId = reportX.id;
+    return true;
+}
+
+const HidParser::ReportItem *HidRawSensor::find(
+        const std::vector<HidParser::ReportPacket> &packets,
+        unsigned int usage, int type, int id) {
+    for (const auto &packet : packets) {
+        if (packet.type != type) {
+            continue;
+        }
+        auto i = std::find_if(
+                packet.reports.begin(), packet.reports.end(),
+                [usage, id](const HidParser::ReportItem &p) {
+                    return p.usage == usage
+                            && (id == -1 || p.id == static_cast<unsigned int>(id));
+                });
+        if (i != packet.reports.end()) {
+            return &(*i);
+        }
+    }
+    return nullptr;
+};
+
+void HidRawSensor::initFeatureValueFromHidDeviceInfo(
+        FeatureValue *featureValue, const HidDevice::HidDeviceInfo &info) {
+    featureValue->name = info.name;
+
+    std::ostringstream ss;
+    ss << info.busType << " "
+       << std::hex << std::setfill('0') << std::setw(4) << info.vendorId
+       << ":" << std::setw(4) << info.productId;
+    featureValue->vendor = ss.str();
+
+    featureValue->permission = "";
+    featureValue->typeString = "";
+    featureValue->type = -1; // invalid type
+    featureValue->version = 1;
+
+    featureValue->maxRange = -1.f;
+    featureValue->resolution = FLT_MAX;
+    featureValue->power = 1.f; // default value, does not have a valid source yet
+
+    featureValue->minDelay = 0;
+    featureValue->maxDelay = 0;
+
+    featureValue->fifoSize = 0;
+    featureValue->fifoMaxSize = 0;
+
+    featureValue->reportModeFlag = SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+    featureValue->isWakeUp = false;
+    memset(featureValue->uuid, 0, sizeof(featureValue->uuid));
+    featureValue->isAndroidCustom = false;
+}
+
+bool HidRawSensor::populateFeatureValueFromFeatureReport(
+        FeatureValue *featureValue, const std::vector<HidParser::ReportPacket> &packets) {
+    SP(HidDevice) device = PROMOTE(mDevice);
+    if (device == nullptr) {
+        return false;
+    }
+
+    std::vector<uint8_t> buffer;
+    for (const auto &packet : packets) {
+        if (packet.type != HidParser::REPORT_TYPE_FEATURE) {
+            continue;
+        }
+
+        if (!device->getFeature(packet.id, &buffer)) {
+            continue;
+        }
+
+        std::string str;
+        using namespace Hid::Sensor::PropertyUsage;
+        for (const auto & r : packet.reports) {
+            switch (r.usage) {
+                case FRIENDLY_NAME:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+                        // invalid friendly name
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str) && !str.empty()) {
+                        featureValue->name = str;
+                    }
+                    break;
+                case SENSOR_MANUFACTURER:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+                        // invalid manufacturer
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str) && !str.empty()) {
+                        featureValue->vendor = str;
+                    }
+                    break;
+                case PERSISTENT_UNIQUE_ID:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1) {
+                        // invalid unique id string
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str) && !str.empty()) {
+                        featureValue->uniqueId = str;
+                    }
+                    break;
+                case SENSOR_DESCRIPTION:
+                    if (!r.isByteAligned() || r.bitSize != 16 || r.count < 1
+                            || (r.bitOffset / 8 + r.count * 2) > buffer.size() ) {
+                        // invalid description
+                        break;
+                    }
+                    if (decodeString(r, buffer, &str)) {
+                        mFeatureInfo.isAndroidCustom = detectAndroidCustomSensor(str);
+                    }
+                    break;
+                default:
+                    // do not care about others
+                    break;
+            }
+        }
+    }
+    return true;
+}
+
+bool HidRawSensor::validateFeatureValueAndBuildSensor() {
+    if (mFeatureInfo.name.empty() || mFeatureInfo.vendor.empty() || mFeatureInfo.typeString.empty()
+            || mFeatureInfo.type <= 0 || mFeatureInfo.maxRange <= 0
+            || mFeatureInfo.resolution <= 0) {
+        return false;
+    }
+
+    switch (mFeatureInfo.reportModeFlag) {
+        case SENSOR_FLAG_CONTINUOUS_MODE:
+        case SENSOR_FLAG_ON_CHANGE_MODE:
+            if (mFeatureInfo.minDelay < 0) {
+                return false;
+            }
+            if (mFeatureInfo.maxDelay != 0 && mFeatureInfo.maxDelay < mFeatureInfo.minDelay) {
+                return false;
+            }
+            break;
+        case SENSOR_FLAG_ONE_SHOT_MODE:
+            if (mFeatureInfo.minDelay != -1 && mFeatureInfo.maxDelay != 0) {
+                return false;
+            }
+            break;
+        case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
+            if (mFeatureInfo.minDelay != -1 && mFeatureInfo.maxDelay != 0) {
+                return false;
+            }
+            break;
+        default:
+            break;
+    }
+
+    if (mFeatureInfo.fifoMaxSize < mFeatureInfo.fifoSize) {
+        return false;
+    }
+
+    // initialize uuid field, use name, vendor and uniqueId
+    if (mFeatureInfo.name.size() >= 4
+            && mFeatureInfo.vendor.size() >= 4
+            && mFeatureInfo.typeString.size() >= 4
+            && mFeatureInfo.uniqueId.size() >= 4) {
+        uint32_t tmp[4], h;
+        std::hash<std::string> stringHash;
+        h = stringHash(mFeatureInfo.uniqueId);
+        tmp[0] = stringHash(mFeatureInfo.name) ^ h;
+        tmp[1] = stringHash(mFeatureInfo.vendor) ^ h;
+        tmp[2] = stringHash(mFeatureInfo.typeString) ^ h;
+        tmp[3] = tmp[0] ^ tmp[1] ^ tmp[2];
+        memcpy(mFeatureInfo.uuid, tmp, sizeof(mFeatureInfo.uuid));
+    }
+
+    mSensor = (sensor_t) {
+        mFeatureInfo.name.c_str(),                 // name
+        mFeatureInfo.vendor.c_str(),               // vendor
+        mFeatureInfo.version,                      // version
+        -1,                                        // handle, dummy number here
+        mFeatureInfo.type,
+        mFeatureInfo.maxRange,                     // maxRange
+        mFeatureInfo.resolution,                   // resolution
+        mFeatureInfo.power,                        // power
+        mFeatureInfo.minDelay,                     // minDelay
+        (uint32_t)mFeatureInfo.fifoSize,           // fifoReservedEventCount
+        (uint32_t)mFeatureInfo.fifoMaxSize,        // fifoMaxEventCount
+        mFeatureInfo.typeString.c_str(),           // type string
+        mFeatureInfo.permission.c_str(),           // requiredPermission
+        (long)mFeatureInfo.maxDelay,               // maxDelay
+        mFeatureInfo.reportModeFlag | (mFeatureInfo.isWakeUp ? 1 : 0),
+        { NULL, NULL }
+    };
+    return true;
+}
+
+bool HidRawSensor::decodeString(
+        const HidParser::ReportItem &report, const std::vector<uint8_t> &buffer, std::string *d) {
+    if (!report.isByteAligned() || report.bitSize != 16 || report.count < 1) {
+        return false;
+    }
+
+    size_t offset = report.bitOffset / 8;
+    if (offset + report.count * 2 > buffer.size()) {
+        return false;
+    }
+
+    std::vector<uint16_t> data(report.count);
+    auto i = data.begin();
+    auto j = buffer.begin() + offset;
+    for ( ; i != data.end(); ++i, j += sizeof(uint16_t)) {
+        // hid specified little endian
+        *i = *j + (*(j + 1) << 8);
+    }
+    std::wstring wstr(data.begin(), data.end());
+
+    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
+    *d = converter.to_bytes(wstr);
+    return true;
+}
+
+std::vector<std::string> split(const std::string &text, char sep) {
+    std::vector<std::string> tokens;
+    size_t start = 0, end = 0;
+    while ((end = text.find(sep, start)) != std::string::npos) {
+        if (end != start) {
+            tokens.push_back(text.substr(start, end - start));
+        }
+        start = end + 1;
+    }
+    if (end != start) {
+        tokens.push_back(text.substr(start));
+    }
+    return tokens;
+}
+
+bool HidRawSensor::detectAndroidCustomSensor(const std::string &description) {
+    size_t nullPosition = description.find('\0');
+    if (nullPosition == std::string::npos) {
+        return false;
+    }
+    const std::string prefix("#ANDROID#");
+    if (description.find(prefix, nullPosition + 1) != nullPosition + 1) {
+        return false;
+    }
+
+    std::string str(description.c_str() + nullPosition + 1 + prefix.size());
+
+    // Format for predefined sensor types:
+    // #ANDROID#nn,[C|X|T|S],[B|0],[W|N]
+    // Format for vendor type sensor
+    // #ANDROID#xxx.yyy.zzz,[C|X|T|S],[B|0],[W|N]
+    //
+    // C: continuous
+    // X: on-change
+    // T: one-shot
+    // S: special trigger
+    //
+    // B: body permission
+    // 0: no permission required
+    std::vector<std::string> segments;
+    size_t start = 0, end = 0;
+    while ((end = str.find(',', start)) != std::string::npos) {
+        if (end != start) {
+            segments.push_back(str.substr(start, end - start));
+        }
+        start = end + 1;
+    }
+    if (end != start) {
+        segments.push_back(str.substr(start));
+    }
+
+    if (segments.size() < 4) {
+        LOG_E << "Not enough segments in android custom description" << LOG_ENDL;
+        return false;
+    }
+
+    // type
+    bool typeParsed = false;
+    if (!segments[0].empty()) {
+        if (::isdigit(segments[0][0])) {
+            int type = ::atoi(segments[0].c_str());
+            // all supported types here
+            switch (type) {
+                case SENSOR_TYPE_HEART_RATE:
+                    mFeatureInfo.type = SENSOR_TYPE_HEART_RATE;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_HEART_RATE;
+                    typeParsed = true;
+                    break;
+                case SENSOR_TYPE_AMBIENT_TEMPERATURE:
+                    mFeatureInfo.type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
+                    typeParsed = true;
+                case SENSOR_TYPE_LIGHT:
+                    mFeatureInfo.type = SENSOR_TYPE_LIGHT;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_LIGHT;
+                    typeParsed = true;
+                    break;
+                case SENSOR_TYPE_PRESSURE:
+                    mFeatureInfo.type = SENSOR_TYPE_PRESSURE;
+                    mFeatureInfo.typeString = SENSOR_STRING_TYPE_PRESSURE;
+                    typeParsed = true;
+                    break;
+                default:
+                    LOG_W << "Android type " << type << " has not been supported yet" << LOG_ENDL;
+                    break;
+            }
+        } else {
+            // assume a xxx.yyy.zzz format
+            std::ostringstream s;
+            bool lastIsDot = true;
+            for (auto c : segments[0]) {
+                if (::isalpha(c)) {
+                    s << static_cast<char>(c);
+                    lastIsDot = false;
+                } else if (!lastIsDot && c == '.') {
+                    s << static_cast<char>(c);
+                    lastIsDot = true;
+                } else {
+                    break;
+                }
+            }
+            if (s.str() == segments[0]) {
+                mFeatureInfo.type = SENSOR_TYPE_DEVICE_PRIVATE_BASE;
+                mFeatureInfo.typeString = CUSTOM_TYPE_PREFIX + s.str();
+                typeParsed = true;
+            }
+        }
+    }
+
+    // reporting type
+    bool reportingModeParsed = false;
+    if (segments[1].size() == 1) {
+        switch (segments[1][0]) {
+            case 'C':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
+                reportingModeParsed = true;
+                break;
+            case 'X':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_ON_CHANGE_MODE;
+                reportingModeParsed = true;
+                break;
+            case 'T':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_ONE_SHOT_MODE;
+                reportingModeParsed = true;
+                break;
+            case 'S':
+                mFeatureInfo.reportModeFlag = SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+                reportingModeParsed = true;
+                break;
+            default:
+                LOG_E << "Undefined reporting mode designation " << segments[1] << LOG_ENDL;
+        }
+    }
+
+    // permission parsed
+    bool permissionParsed = false;
+    if (segments[2].size() == 1) {
+        switch (segments[2][0]) {
+            case 'B':
+                mFeatureInfo.permission = SENSOR_PERMISSION_BODY_SENSORS;
+                permissionParsed = true;
+                break;
+            case '0':
+                mFeatureInfo.permission = "";
+                permissionParsed = true;
+                break;
+            default:
+                LOG_E << "Undefined permission designation " << segments[2] << LOG_ENDL;
+        }
+    }
+
+    // wake up
+    bool wakeUpParsed = false;
+    if (segments[3].size() == 1) {
+        switch (segments[3][0]) {
+            case 'W':
+                mFeatureInfo.isWakeUp = true;
+                wakeUpParsed = true;
+                break;
+            case 'N':
+                mFeatureInfo.isWakeUp = false;
+                wakeUpParsed = true;
+                break;
+            default:
+                LOG_E << "Undefined wake up designation " << segments[3] << LOG_ENDL;
+        }
+    }
+
+    int ret = typeParsed && reportingModeParsed && permissionParsed && wakeUpParsed;
+    if (!ret) {
+        LOG_D << "detectAndroidCustomSensor typeParsed: " << typeParsed
+              << " reportingModeParsed: "  << reportingModeParsed
+              << " permissionParsed: " << permissionParsed
+              << " wakeUpParsed: " << wakeUpParsed << LOG_ENDL;
+    }
+    return ret;
+}
+
+bool HidRawSensor::findSensorControlUsage(const std::vector<HidParser::ReportPacket> &packets) {
+    using namespace Hid::Sensor::PropertyUsage;
+    using namespace Hid::Sensor::RawMinMax;
+
+    //REPORTING_STATE
+    const HidParser::ReportItem *reportingState
+            = find(packets, REPORTING_STATE, HidParser::REPORT_TYPE_FEATURE);
+
+    if (reportingState == nullptr
+            || !reportingState->isByteAligned()
+            || reportingState->bitSize != 8
+            || reportingState->minRaw != REPORTING_STATE_MIN
+            || reportingState->maxRaw != REPORTING_STATE_MAX) {
+        LOG_W << "Cannot find valid reporting state feature" << LOG_ENDL;
+    } else {
+        mReportingStateId = reportingState->id;
+        mReportingStateOffset = reportingState->bitOffset / 8;
+    }
+
+    //POWER_STATE
+    const HidParser::ReportItem *powerState
+            = find(packets, POWER_STATE, HidParser::REPORT_TYPE_FEATURE);
+    if (powerState == nullptr
+            || !powerState->isByteAligned()
+            || powerState->bitSize != 8
+            || powerState->minRaw != POWER_STATE_MIN
+            || powerState->maxRaw != POWER_STATE_MAX) {
+        LOG_W << "Cannot find valid power state feature" << LOG_ENDL;
+    } else {
+        mPowerStateId = powerState->id;
+        mPowerStateOffset = powerState->bitOffset / 8;
+    }
+
+    //REPORT_INTERVAL
+    const HidParser::ReportItem *reportInterval
+            = find(packets, REPORT_INTERVAL, HidParser::REPORT_TYPE_FEATURE);
+    if (reportInterval == nullptr
+            || !reportInterval->isByteAligned()
+            || reportInterval->minRaw < 0
+            || (reportInterval->bitSize != 16 && reportInterval->bitSize != 32)) {
+        LOG_W << "Cannot find valid report interval feature" << LOG_ENDL;
+    } else {
+        mReportIntervalId = reportInterval->id;
+        mReportIntervalOffset = reportInterval->bitOffset / 8;
+        mReportIntervalSize = reportInterval->bitSize / 8;
+
+        mFeatureInfo.minDelay = std::max(static_cast<int64_t>(1), reportInterval->minRaw) * 1000;
+        mFeatureInfo.maxDelay = std::min(static_cast<int64_t>(1000000),
+                                    reportInterval->maxRaw) * 1000; // maximum 1000 second
+    }
+    return true;
+    return (mPowerStateId >= 0 || mReportingStateId >= 0) && mReportIntervalId >= 0;
+}
+
+const sensor_t* HidRawSensor::getSensor() const {
+    return &mSensor;
+}
+
+void HidRawSensor::getUuid(uint8_t* uuid) const {
+    memcpy(uuid, mFeatureInfo.uuid, sizeof(mFeatureInfo.uuid));
+}
+
+int HidRawSensor::enable(bool enable) {
+    using namespace Hid::Sensor::StateValue;
+    SP(HidDevice) device = PROMOTE(mDevice);
+
+    if (device == nullptr) {
+        return NO_INIT;
+    }
+
+    if (enable == mEnabled) {
+        return NO_ERROR;
+    }
+
+    std::vector<uint8_t> buffer;
+    bool setPowerOk = true;
+    if (mPowerStateId >= 0) {
+        setPowerOk = false;
+        uint8_t id = static_cast<uint8_t>(mPowerStateId);
+        if (device->getFeature(id, &buffer)
+                && buffer.size() > mPowerStateOffset) {
+            buffer[mPowerStateOffset] = enable ? POWER_STATE_FULL_POWER : POWER_STATE_POWER_OFF;
+            setPowerOk = device->setFeature(id, buffer);
+        } else {
+            LOG_E << "enable: changing POWER STATE failed" << LOG_ENDL;
+        }
+    }
+
+    bool setReportingOk = true;
+    if (mReportingStateId >= 0) {
+        setReportingOk = false;
+        uint8_t id = static_cast<uint8_t>(mReportingStateId);
+        if (device->getFeature(id, &buffer)
+                && buffer.size() > mReportingStateOffset) {
+            buffer[mReportingStateOffset]
+                    = enable ? REPORTING_STATE_ALL_EVENT : REPORTING_STATE_NO_EVENT;
+            setReportingOk = device->setFeature(id, buffer);
+        } else {
+            LOG_E << "enable: changing REPORTING STATE failed" << LOG_ENDL;
+        }
+    }
+
+    if (setPowerOk && setReportingOk) {
+        mEnabled = enable;
+        return NO_ERROR;
+    } else {
+        return INVALID_OPERATION;
+    }
+}
+
+int HidRawSensor::batch(int64_t samplingPeriod, int64_t batchingPeriod) {
+    SP(HidDevice) device = PROMOTE(mDevice);
+    if (device == nullptr) {
+        return NO_INIT;
+    }
+
+    if (samplingPeriod < 0 || batchingPeriod < 0) {
+        return BAD_VALUE;
+    }
+
+    bool needRefresh = mSamplingPeriod != samplingPeriod || mBatchingPeriod != batchingPeriod;
+    std::vector<uint8_t> buffer;
+
+    bool ok = true;
+    if (needRefresh && mReportIntervalId >= 0) {
+        ok = false;
+        uint8_t id = static_cast<uint8_t>(mReportIntervalId);
+        if (device->getFeature(id, &buffer)
+                && buffer.size() >= mReportIntervalOffset + mReportIntervalSize) {
+            int64_t periodMs = samplingPeriod / 1000000; //ns -> ms
+            switch (mReportIntervalSize) {
+                case sizeof(uint16_t):
+                    periodMs = std::min(periodMs, static_cast<int64_t>(UINT16_MAX));
+                    buffer[mReportIntervalOffset] = periodMs & 0xFF;
+                    buffer[mReportIntervalOffset + 1] = (periodMs >> 8) & 0xFF;
+                case sizeof(uint32_t):
+                    periodMs = std::min(periodMs, static_cast<int64_t>(UINT32_MAX));
+                    buffer[mReportIntervalOffset] = periodMs & 0xFF;
+                    buffer[mReportIntervalOffset + 1] = (periodMs >> 8) & 0xFF;
+                    buffer[mReportIntervalOffset + 2] = (periodMs >> 16) & 0xFF;
+                    buffer[mReportIntervalOffset + 3] = (periodMs >> 24) & 0xFF;
+            }
+            ok = device->setFeature(id, buffer);
+        }
+    }
+
+    if (ok) {
+        mSamplingPeriod = samplingPeriod;
+        mBatchingPeriod = batchingPeriod;
+        return NO_ERROR;
+    } else {
+        return INVALID_OPERATION;
+    }
+}
+
+void HidRawSensor::handleInput(uint8_t id, const std::vector<uint8_t> &message) {
+    if (id != mInputReportId || mEnabled == false) {
+        return;
+    }
+    sensors_event_t event = {
+        .version = sizeof(event),
+        .sensor = -1,
+        .type = mSensor.type
+    };
+    bool valid = true;
+    for (const auto &rec : mTranslateTable) {
+        int64_t v = (message[rec.byteOffset + rec.byteSize - 1] & 0x80) ? -1 : 0;
+        for (int i = static_cast<int>(rec.byteSize) - 1; i >= 0; --i) {
+            v = (v << 8) | message[rec.byteOffset + i]; // HID is little endian
+        }
+
+        switch (rec.type) {
+            case TYPE_FLOAT:
+                if (v > rec.maxValue || v < rec.minValue) {
+                    valid = false;
+                }
+                event.data[rec.index] = rec.a * (v + rec.b);
+                break;
+            case TYPE_INT64:
+                if (v > rec.maxValue || v < rec.minValue) {
+                    valid = false;
+                }
+                event.u64.data[rec.index] = v + rec.b;
+                break;
+            case TYPE_ACCURACY:
+                event.magnetic.status = (v & 0xFF) + rec.b;
+                break;
+        }
+    }
+    if (!valid) {
+        LOG_V << "Range error observed in decoding, discard" << LOG_ENDL;
+    }
+    event.timestamp = -1;
+    generateEvent(event);
+}
+
+std::string HidRawSensor::dump() const {
+    std::ostringstream ss;
+    ss << "Feature Values " << LOG_ENDL
+          << "  name: " << mFeatureInfo.name << LOG_ENDL
+          << "  vendor: " << mFeatureInfo.vendor << LOG_ENDL
+          << "  permission: " << mFeatureInfo.permission << LOG_ENDL
+          << "  typeString: " << mFeatureInfo.typeString << LOG_ENDL
+          << "  type: " << mFeatureInfo.type << LOG_ENDL
+          << "  maxRange: " << mFeatureInfo.maxRange << LOG_ENDL
+          << "  resolution: " << mFeatureInfo.resolution << LOG_ENDL
+          << "  power: " << mFeatureInfo.power << LOG_ENDL
+          << "  minDelay: " << mFeatureInfo.minDelay << LOG_ENDL
+          << "  maxDelay: " << mFeatureInfo.maxDelay << LOG_ENDL
+          << "  fifoSize: " << mFeatureInfo.fifoSize << LOG_ENDL
+          << "  fifoMaxSize: " << mFeatureInfo.fifoMaxSize << LOG_ENDL
+          << "  reportModeFlag: " << mFeatureInfo.reportModeFlag << LOG_ENDL
+          << "  isWakeUp: " << (mFeatureInfo.isWakeUp ? "true" : "false") << LOG_ENDL
+          << "  uniqueId: " << mFeatureInfo.uniqueId << LOG_ENDL
+          << "  uuid: ";
+
+    ss << std::hex << std::setfill('0');
+    for (auto d : mFeatureInfo.uuid) {
+          ss << std::setw(2) << static_cast<int>(d) << " ";
+    }
+    ss << std::dec << std::setfill(' ') << LOG_ENDL;
+
+    ss << "Input report id: " << mInputReportId << LOG_ENDL;
+    for (const auto &t : mTranslateTable) {
+        ss << "  type, index: " << t.type << ", " << t.index
+              << "; min,max: " << t.minValue << ", " << t.maxValue
+              << "; byte-offset,size: " << t.byteOffset << ", " << t.byteSize
+              << "; scaling,bias: " << t.a << ", " << t.b << LOG_ENDL;
+    }
+
+    ss << "Control features: " << LOG_ENDL;
+    ss << "  Power state ";
+    if (mPowerStateId >= 0) {
+        ss << "found, id: " << mPowerStateId
+              << " offset: " << mPowerStateOffset << LOG_ENDL;
+    } else {
+        ss << "not found" << LOG_ENDL;
+    }
+
+    ss << "  Reporting state ";
+    if (mReportingStateId >= 0) {
+        ss << "found, id: " << mReportingStateId
+              << " offset: " << mReportingStateOffset << LOG_ENDL;
+    } else {
+        ss << "not found" << LOG_ENDL;
+    }
+
+    ss << "  Report interval ";
+    if (mReportIntervalId >= 0) {
+        ss << "found, id: " << mReportIntervalId
+              << " offset: " << mReportIntervalOffset
+              << " size: " << mReportIntervalSize << LOG_ENDL;
+    } else {
+        ss << "not found" << LOG_ENDL;
+    }
+    return ss.str();
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h
new file mode 100644
index 0000000..2dd32b6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
+
+#include "BaseSensorObject.h"
+#include "HidDevice.h"
+#include "Utils.h"
+
+#include <HidParser.h>
+#include <hardware/sensors.h>
+
+namespace android {
+namespace SensorHalExt {
+
+using HidUtil::HidParser;
+using ReportPacket = HidParser::ReportPacket;
+using ReportItem = HidParser::ReportItem;
+
+class HidRawSensor : public BaseSensorObject {
+    friend class HidRawSensorTest;
+    friend class HidRawDeviceTest;
+public:
+    HidRawSensor(SP(HidDevice) device, uint32_t usage,
+                 const std::vector<HidParser::ReportPacket> &report);
+
+    // implements BaseSensorObject
+    virtual const sensor_t* getSensor() const;
+    virtual void getUuid(uint8_t* uuid) const;
+    virtual int enable(bool enable);
+    virtual int batch(int64_t samplePeriod, int64_t batchPeriod); // unit nano-seconds
+
+    // handle input report received
+    void handleInput(uint8_t id, const std::vector<uint8_t> &message);
+
+    // indicate if the HidRawSensor is a valid one
+    bool isValid() const { return mValid; };
+
+private:
+
+    // structure used for holding descriptor parse result for each report field
+    enum {
+        TYPE_FLOAT,
+        TYPE_INT64,
+        TYPE_ACCURACY
+    };
+    struct ReportTranslateRecord {
+        int type;
+        int index;
+        int64_t maxValue;
+        int64_t minValue;
+        size_t byteOffset;
+        size_t byteSize;
+        double a;
+        int64_t b;
+    };
+
+    // sensor related information parsed from HID descriptor
+    struct FeatureValue {
+        // information needed to furnish sensor_t structure (see hardware/sensors.h)
+        std::string name;
+        std::string vendor;
+        std::string permission;
+        std::string typeString;
+        int32_t type;
+        int version;
+        float maxRange;
+        float resolution;
+        float power;
+        int32_t minDelay;
+        int64_t maxDelay;
+        size_t fifoSize;
+        size_t fifoMaxSize;
+        uint32_t reportModeFlag;
+        bool isWakeUp;
+
+        // dynamic sensor specific
+        std::string uniqueId;
+        uint8_t uuid[16];
+
+        // if the device is custom sensor HID device that furnished android specific descriptors
+        bool isAndroidCustom;
+    };
+
+    // helper function to find the first report item with specified usage, type and id.
+    // if parameter id is omitted, this function looks for usage with all ids.
+    // return nullptr if nothing is found.
+    static const HidParser::ReportItem* find
+            (const std::vector<HidParser::ReportPacket> &packets,
+            unsigned int usage, int type, int id = -1);
+
+    // helper function to decode std::string from HID feature report buffer.
+    static bool decodeString(
+            const HidParser::ReportItem &report,
+            const std::vector<uint8_t> &buffer, std::string *d);
+
+    // initialize default feature values default based on hid device info
+    static void initFeatureValueFromHidDeviceInfo(
+            FeatureValue *featureValue, const HidDevice::HidDeviceInfo &info);
+
+    // populates feature values from descripitors and hid feature reports
+    bool populateFeatureValueFromFeatureReport(
+            FeatureValue *featureValue, const std::vector<HidParser::ReportPacket> &packets);
+
+    // validate feature values and construct sensor_t structure if values are ok.
+    bool validateFeatureValueAndBuildSensor();
+
+    // helper function to find sensor control feature usage from packets
+    bool findSensorControlUsage(const std::vector<HidParser::ReportPacket> &packets);
+
+    // try to parse sensor description feature value to see if it matches
+    // android specified custom sensor definition.
+    bool detectAndroidCustomSensor(const std::string &description);
+
+    // process HID sensor spec defined three axis sensors usages: accel, gyro, mag.
+    bool processTriAxisUsage(const std::vector<HidParser::ReportPacket> &packets,
+            uint32_t usageX, uint32_t usageY, uint32_t usageZ, double defaultScaling = 1);
+
+    // process HID snesor spec defined orientation(quaternion) sensor usages.
+    bool processQuaternionUsage(const std::vector<HidParser::ReportPacket> &packets);
+
+    // dump data for test/debug purpose
+    std::string dump() const;
+
+    // Features for control sensor
+    int mReportingStateId;
+    unsigned int mReportingStateOffset;
+
+    int mPowerStateId;
+    unsigned int mPowerStateOffset;
+
+    int mReportIntervalId;
+    unsigned int mReportIntervalOffset;
+    unsigned int mReportIntervalSize;
+
+    // Input report translate table
+    std::vector<ReportTranslateRecord> mTranslateTable;
+    unsigned mInputReportId;
+
+    FeatureValue mFeatureInfo;
+    sensor_t mSensor;
+
+    // runtime states variable
+    bool mEnabled;
+    int64_t mSamplingPeriod;    // ns
+    int64_t mBatchingPeriod;    // ns
+
+    WP(HidDevice) mDevice;
+    bool mValid;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp
new file mode 100644
index 0000000..6bf34bc
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidRawSensorDaemon.h"
+#include "ConnectionDetector.h"
+#include "DynamicSensorManager.h"
+#include "HidRawSensorDevice.h"
+
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <iomanip>
+#include <sstream>
+
+#define DEV_PATH                "/dev/"
+#define DEV_NAME_REGEX          "^hidraw[0-9]+$"
+
+namespace android {
+namespace SensorHalExt {
+
+HidRawSensorDaemon::HidRawSensorDaemon(DynamicSensorManager& manager)
+        : BaseDynamicSensorDaemon(manager) {
+    mDetector = new FileConnectionDetector(
+            this, std::string(DEV_PATH), std::string(DEV_NAME_REGEX));
+}
+
+BaseSensorVector HidRawSensorDaemon::createSensor(const std::string &deviceKey) {
+    BaseSensorVector ret;
+    sp<HidRawSensorDevice> device(HidRawSensorDevice::create(deviceKey));
+
+    if (device != nullptr) {
+        ALOGV("created HidRawSensorDevice(%p) successfully on device %s contains %zu sensors",
+              device.get(), deviceKey.c_str(), device->getSensors().size());
+
+        // convert type
+        for (auto &i : device->getSensors()) {
+            ret.push_back(i);
+        }
+        mHidRawSensorDevices.emplace(deviceKey, device);
+    } else {
+        ALOGE("failed to create HidRawSensorDevice object");
+    }
+
+    ALOGE("return %zu sensors", ret.size());
+    return ret;
+}
+
+void HidRawSensorDaemon::removeSensor(const std::string &deviceKey) {
+    mHidRawSensorDevices.erase(deviceKey);
+}
+
+} // namespace SensorHalExt
+} // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDaemon.h b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.h
new file mode 100644
index 0000000..fc4b2a2
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDaemon.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DAEMON_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DAEMON_H
+
+#include "BaseDynamicSensorDaemon.h"
+
+#include <HidParser.h>
+#include <hardware/sensors.h>
+#include <utils/Thread.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+
+using HidUtil::HidParser;
+using HidUtil::HidReport;
+using HidUtil::HidItem;
+
+namespace android {
+namespace SensorHalExt {
+
+class HidRawSensorDevice;
+class ConnectionDetector;
+
+class HidRawSensorDaemon : public BaseDynamicSensorDaemon {
+    friend class HidRawSensorDaemonTest;
+public:
+    HidRawSensorDaemon(DynamicSensorManager& manager);
+    virtual ~HidRawSensorDaemon() = default;
+private:
+    virtual BaseSensorVector createSensor(const std::string &deviceKey);
+    virtual void removeSensor(const std::string &deviceKey);
+
+    class HidRawSensor;
+    void registerExisting();
+
+    sp<ConnectionDetector> mDetector;
+    std::unordered_map<std::string, sp<HidRawSensorDevice>> mHidRawSensorDevices;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DAEMON_H
+
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
new file mode 100644
index 0000000..16e9060
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "HidRawSensorDevice.h"
+#include "HidRawSensor.h"
+#include "HidSensorDef.h"
+
+#include <utils/Log.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+#include <sys/ioctl.h>
+
+#include <set>
+
+namespace android {
+namespace SensorHalExt {
+
+using namespace Hid::Sensor::SensorTypeUsage;
+using namespace Hid::Sensor::PropertyUsage;
+
+const std::unordered_set<unsigned int> HidRawSensorDevice::sInterested{
+        ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM};
+
+sp<HidRawSensorDevice> HidRawSensorDevice::create(const std::string &devName) {
+    sp<HidRawSensorDevice> device(new HidRawSensorDevice(devName));
+    // remove +1 strong count added by constructor
+    device->decStrong(device.get());
+
+    if (device->mValid) {
+        return device;
+    } else {
+        return nullptr;
+    }
+}
+
+HidRawSensorDevice::HidRawSensorDevice(const std::string &devName)
+        : RefBase(), HidRawDevice(devName, sInterested),
+          Thread(false /*canCallJava*/), mValid(false) {
+    if (!HidRawDevice::isValid()) {
+        return;
+    }
+    // create HidRawSensor objects from digest
+    // HidRawSensor object will take sp<HidRawSensorDevice> as parameter, so increment strong count
+    // to prevent "this" being destructed.
+    this->incStrong(this);
+    for (const auto &digest : mDigestVector) { // for each usage - vec<ReportPacket> pair
+        uint32_t usage = static_cast<uint32_t>(digest.fullUsage);
+        sp<HidRawSensor> s(new HidRawSensor(this, usage, digest.packets));
+        if (s->isValid()) {
+            for (const auto &packet : digest.packets) {
+                if (packet.type == HidParser::REPORT_TYPE_INPUT) { // only used for input mapping
+                    mSensors.emplace(packet.id/* report id*/, s);
+                }
+            }
+        }
+    }
+    if (mSensors.size() == 0) {
+        return;
+    }
+
+    run("HidRawSensor");
+    mValid = true;
+}
+
+HidRawSensorDevice::~HidRawSensorDevice() {
+    ALOGV("~HidRawSensorDevice %p", this);
+    requestExitAndWait();
+    ALOGV("~HidRawSensorDevice %p, thread exited", this);
+}
+
+bool HidRawSensorDevice::threadLoop() {
+    ALOGV("Hid Raw Device thread started %p", this);
+    std::vector<uint8_t> buffer;
+    bool ret;
+    uint8_t usageId;
+
+    while(!Thread::exitPending()) {
+        ret = receiveReport(&usageId, &buffer);
+        if (!ret) {
+            break;
+        }
+
+        auto i = mSensors.find(usageId);
+        if (i == mSensors.end()) {
+            ALOGW("Input of unknow usage id %u received", usageId);
+            continue;
+        }
+
+        i->second->handleInput(usageId, buffer);
+    }
+
+    ALOGI("Hid Raw Device thread ended for %p", this);
+    return false;
+}
+
+BaseSensorVector HidRawSensorDevice::getSensors() const {
+    BaseSensorVector ret;
+    std::set<sp<BaseSensorObject>> set;
+    for (const auto &s : mSensors) {
+        if (set.find(s.second) == set.end()) {
+            ret.push_back(s.second);
+            set.insert(s.second);
+        }
+    }
+    return ret;
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDevice.h b/modules/sensors/dynamic_sensor/HidRawSensorDevice.h
new file mode 100644
index 0000000..06d435e
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDevice.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DEVICE_H
+#define ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_DEVICE_H
+
+#include "BaseSensorObject.h"
+#include "BaseDynamicSensorDaemon.h" // BaseSensorVector
+#include "HidRawDevice.h"
+#include "HidRawSensor.h"
+
+#include <HidParser.h>
+#include <utils/Thread.h>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace SensorHalExt {
+
+class HidRawSensorDevice : public HidRawDevice, public Thread {
+public:
+    static sp<HidRawSensorDevice> create(const std::string &devName);
+    virtual ~HidRawSensorDevice();
+
+    // get a list of sensors associated with this device
+    BaseSensorVector getSensors() const;
+private:
+    static const std::unordered_set<unsigned int> sInterested;
+
+    // constructor will result in +1 strong count
+    explicit HidRawSensorDevice(const std::string &devName);
+    // implement function of Thread
+    virtual bool threadLoop() override;
+    std::unordered_map<unsigned int/*reportId*/, sp<HidRawSensor>> mSensors;
+    bool mValid;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_HIDRAW_DEVICE_H
+
diff --git a/modules/sensors/dynamic_sensor/HidSensorDef.h b/modules/sensors/dynamic_sensor/HidSensorDef.h
new file mode 100644
index 0000000..2728b28
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidSensorDef.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HID_SENSOR_DEF_H_
+#define HID_SENSOR_DEF_H_
+namespace Hid {
+namespace Sensor {
+namespace GeneralUsage {
+enum {
+    STATE = 0x200201,
+    EVENT = 0x200202,
+};
+
+} //namespace Usage
+namespace PropertyUsage {
+enum {
+    FRIENDLY_NAME = 0x200301,
+    MINIMUM_REPORT_INTERVAL = 0x200304,
+    PERSISTENT_UNIQUE_ID = 0x200302,
+    POWER_STATE = 0x200319,
+    RANGE_MAXIMUM = 0x200314,
+    RANGE_MINIMUM = 0x200315,
+    REPORTING_STATE = 0x200316,
+    REPORT_INTERVAL = 0x20030E,
+    RESOLUTION = 0x200313,
+    SAMPLING_RATE =0x200317,
+    SENSOR_CONNECTION_TYPE = 0x200309,
+    SENSOR_DESCRIPTION = 0x200308,
+    SENSOR_MANUFACTURER = 0x200305,
+    SENSOR_MODEL = 0x200306,
+    SENSOR_SERIAL_NUMBER = 0x200307,
+    SENSOR_STATUS = 0x200303,
+};
+} // nsmespace PropertyUsage
+
+namespace SensorTypeUsage {
+enum {
+    ACCELEROMETER_3D = 0x200073,
+    COMPASS_3D = 0x200083,
+    CUSTOM = 0x2000E1,
+    DEVICE_ORIENTATION = 0x20008A,
+    GYROMETER_3D = 0x200076,
+};
+} // namespace SensorTypeUsage
+
+namespace ReportUsage {
+enum {
+    ACCELERATION_X_AXIS = 0x200453,
+    ACCELERATION_Y_AXIS = 0x200454,
+    ACCELERATION_Z_AXIS = 0x200455,
+    ANGULAR_VELOCITY_X_AXIS = 0x200457,
+    ANGULAR_VELOCITY_Y_AXIS = 0x200458,
+    ANGULAR_VELOCITY_Z_AXIS = 0x200459,
+    CUSTOM_VALUE_1 = 0x200544,
+    CUSTOM_VALUE_2 = 0x200545,
+    CUSTOM_VALUE_3 = 0x200546,
+    CUSTOM_VALUE_4 = 0x200547,
+    CUSTOM_VALUE_5 = 0x200548,
+    CUSTOM_VALUE_6 = 0x200549,
+    MAGNETIC_FLUX_X_AXIS = 0x200485,
+    MAGNETIC_FLUX_Y_AXIS = 0x200486,
+    MAGNETIC_FLUX_Z_AXIS = 0x200487,
+    MAGNETOMETER_ACCURACY = 0x200488,
+    ORIENTATION_QUATERNION = 0x200483,
+};
+} // namespace ReportUsage
+
+namespace RawMinMax {
+enum {
+    REPORTING_STATE_MIN = 0,
+    REPORTING_STATE_MAX = 5,
+    POWER_STATE_MIN = 0,
+    POWER_STATE_MAX = 5,
+};
+} // namespace RawMinMax
+
+namespace StateValue {
+enum {
+    POWER_STATE_FULL_POWER = 1,
+    POWER_STATE_POWER_OFF = 5,
+
+    REPORTING_STATE_ALL_EVENT = 1,
+    REPORTING_STATE_NO_EVENT = 0,
+};
+} // StateValue
+} // namespace Sensor
+} // namespace Hid
+#endif // HID_SENSOR_DEF_H_
+
diff --git a/modules/sensors/dynamic_sensor/SensorEventCallback.h b/modules/sensors/dynamic_sensor/SensorEventCallback.h
index b98cd7f..2f79529 100644
--- a/modules/sensors/dynamic_sensor/SensorEventCallback.h
+++ b/modules/sensors/dynamic_sensor/SensorEventCallback.h
@@ -17,12 +17,11 @@
 #ifndef ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
 #define ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
 
+#include "Utils.h"
 #include <hardware/sensors.h>
-#include <utils/RefBase.h>
 
 namespace android {
 namespace SensorHalExt {
-
 class BaseSensorObject;
 
 // if timestamp in sensors_event_t has this value, it will be filled at dispatcher.
@@ -30,7 +29,7 @@
 
 class SensorEventCallback {
 public:
-    virtual int submitEvent(sp<BaseSensorObject> sensor, const sensors_event_t &e) = 0;
+    virtual int submitEvent(SP(BaseSensorObject) sensor, const sensors_event_t &e) = 0;
     virtual ~SensorEventCallback() = default;
 };
 
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/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;
+}
