hikey: Add support for contexthub hal and neonkey / argonkey sensor hal

Compile: make TARGET_SENSOR_MEZZANINE=<mezzanine_name>
         (<mezzanine_name> can be neonkey or argonkey)

Test: builds
Change-Id: I11c2734965b96cb34aef7558b7c822d0e5ea5c65
Signed-off-by: Ben Fennema <fennema@google.com>
diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk
index f605174..a8deb9f 100644
--- a/BoardConfigCommon.mk
+++ b/BoardConfigCommon.mk
@@ -36,7 +36,7 @@
 
 SF_START_GRAPHICS_ALLOCATOR_SERVICE := true
 
-TARGET_AUX_OS_VARIANT_LIST := neonkey
+TARGET_AUX_OS_VARIANT_LIST := neonkey argonkey
 
 BOARD_SEPOLICY_DIRS += device/linaro/hikey/sepolicy
 BOARD_SEPOLICY_DIRS += system/bt/vendor_libs/linux/sepolicy
@@ -44,6 +44,10 @@
 DEVICE_MANIFEST_FILE := device/linaro/hikey/manifest.xml
 DEVICE_MATRIX_FILE := device/linaro/hikey/compatibility_matrix.xml
 
+ifneq ($(TARGET_SENSOR_MEZZANINE),)
+DEVICE_MANIFEST_FILE += device/linaro/hikey/sensorhal/manifest.xml
+endif
+
 ifeq ($(HOST_OS), linux)
 ifeq ($(TARGET_SYSTEMIMAGES_USE_SQUASHFS), true)
 BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := squashfs
diff --git a/device-common.mk b/device-common.mk
index 23863ad..7c35fa7 100644
--- a/device-common.mk
+++ b/device-common.mk
@@ -65,9 +65,6 @@
     android.hardware.memtrack@1.0-service \
     android.hardware.memtrack@1.0-impl
 
-# Nanohub tools
-PRODUCT_PACKAGES += stm32_flash nanoapp_cmd
-
 PRODUCT_PACKAGES +=	TIInit_11.8.32.bts \
 			wl18xx-fw-4.bin \
 			wl18xx-conf.bin
@@ -90,6 +87,29 @@
 PRODUCT_PACKAGES += \
     android.hardware.keymaster@3.0-impl
 
+# Sensor HAL
+ifneq ($(TARGET_SENSOR_MEZZANINE),)
+TARGET_USES_NANOHUB_SENSORHAL := true
+NANOHUB_SENSORHAL_LID_STATE_ENABLED := true
+NANOHUB_SENSORHAL_SENSORLIST := $(LOCAL_PATH)/sensorhal/sensorlist_$(TARGET_SENSOR_MEZZANINE).cpp
+NANOHUB_SENSORHAL_DIRECT_REPORT_ENABLED := true
+NANOHUB_SENSORHAL_DYNAMIC_SENSOR_EXT_ENABLED := true
+
+PRODUCT_PACKAGES += \
+    context_hub.default \
+    android.hardware.sensors@1.0-service \
+    android.hardware.sensors@1.0-impl \
+    android.hardware.contexthub@1.0-service \
+    android.hardware.contexthub@1.0-impl \
+    sensors.$(TARGET_PRODUCT)
+
+# Nanohub tools
+PRODUCT_PACKAGES += stm32_flash nanoapp_cmd nanotool
+
+PRODUCT_COPY_FILES += \
+    device/linaro/hikey/init.common.nanohub.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.nanohub.rc
+endif
+
 # Use Launcher3
 PRODUCT_PACKAGES += Launcher3
 
@@ -110,7 +130,6 @@
         frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
         frameworks/native/data/etc/android.hardware.bluetooth.xml:system/etc/permissions/android.hardware.bluetooth.xml \
         frameworks/native/data/etc/android.hardware.bluetooth_le.xml:system/etc/permissions/android.hardware.bluetooth_le.xml \
-        device/linaro/hikey/manifest.xml:system/vendor/manifest.xml \
         device/linaro/hikey/wpa_supplicant.conf:system/etc/wifi/wpa_supplicant.conf
 
 # audio policy configuration
diff --git a/hikey/BoardConfig.mk b/hikey/BoardConfig.mk
index 0cf3527..26389c1 100644
--- a/hikey/BoardConfig.mk
+++ b/hikey/BoardConfig.mk
@@ -12,6 +12,10 @@
 BOARD_KERNEL_CMDLINE := console=ttyFIQ0 androidboot.console=ttyFIQ0 androidboot.hardware=hikey firmware_class.path=/system/etc/firmware efi=noruntime
 endif
 
+ifneq ($(TARGET_SENSOR_MEZZANINE),)
+BOARD_KERNEL_CMDLINE += overlay_mgr.overlay_dt_entry=hardware_cfg_$(TARGET_SENSOR_MEZZANINE)
+endif
+
 ## printk.devkmsg only has meaning for kernel 4.9 and later
 ## it would be ignored by kernel 3.18 and kernel 4.4
 BOARD_KERNEL_CMDLINE += printk.devkmsg=on
diff --git a/hikey960/BoardConfig.mk b/hikey960/BoardConfig.mk
index 00598e7..0253141 100644
--- a/hikey960/BoardConfig.mk
+++ b/hikey960/BoardConfig.mk
@@ -10,6 +10,9 @@
 
 BOARD_KERNEL_CMDLINE := androidboot.hardware=hikey960 console=ttyFIQ0 androidboot.console=ttyFIQ0
 BOARD_KERNEL_CMDLINE += firmware_class.path=/system/etc/firmware loglevel=15
+ifneq ($(TARGET_SENSOR_MEZZANINE),)
+BOARD_KERNEL_CMDLINE += overlay_mgr.overlay_dt_entry=hardware_cfg_$(TARGET_SENSOR_MEZZANINE)
+endif
 BOARD_MKBOOTIMG_ARGS := --base 0x0 --tags_offset 0x07a00000 --kernel_offset 0x00080000 --ramdisk_offset 0x07c00000
 
 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2768240640   # 2640MB
diff --git a/init.common.nanohub.rc b/init.common.nanohub.rc
new file mode 100644
index 0000000..7f6ff93
--- /dev/null
+++ b/init.common.nanohub.rc
@@ -0,0 +1,7 @@
+on post-fs-data
+    mkdir /data/vendor/sensor
+    chown root system /data/vendor/sensor
+    chmod 0770 /data/vendor/sensor
+
+    mkdir /data/system/nanohub_lock
+    restorecon /data/system/nanohub_lock
diff --git a/sensorhal/manifest.xml b/sensorhal/manifest.xml
new file mode 100644
index 0000000..7dc1856
--- /dev/null
+++ b/sensorhal/manifest.xml
@@ -0,0 +1,20 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.contexthub</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IContexthub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl">
+        <name>android.hardware.sensors</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/sensorhal/sensorlist_argonkey.cpp b/sensorhal/sensorlist_argonkey.cpp
new file mode 100644
index 0000000..d5845b7
--- /dev/null
+++ b/sensorhal/sensorlist_argonkey.cpp
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sensorlist.h"
+
+#include <math.h>
+
+#include "hubdefs.h"
+
+using namespace android;
+
+const int kVersion = 1;
+
+const float kMinSampleRateHzAccel = 0.8125f;
+const float kMaxSampleRateHzAccel = 416.0f;
+const float kAccelRangeG = 8.0f;
+extern const float kScaleAccel = 0.00239364f;
+
+const float kMinSampleRateHzGyro = 0.8125f;
+const float kMaxSampleRateHzGyro = 416.0f;
+
+const float kMinSampleRateHzMag = 0.8125f;
+const float kMaxSampleRateHzMag = 104.0f;
+extern const float kScaleMag = 0.15f;
+
+const float kMinSampleRateHzPressure = 1.0f;
+const float kMaxSampleRateHzPressure = 75.0f;
+
+const float kMinSampleRateHzTemperature = 1.0f;
+const float kMaxSampleRateHzTemperature = 75.0f;
+
+const float kMinSampleRateHzHumidity = 1.0f;
+const float kMaxSampleRateHzHumidity = 12.5f;
+
+#ifdef HAVE_VL53L0X_DRIVER
+const float kMinSampleRateHzProximity = 0.1f;
+const float kMaxSampleRateHzProximity = 5.0f;
+#endif
+
+const float kMinSampleRateHzLight = 10.0f;
+const float kMaxSampleRateHzLight = 10.0f;
+
+const float kMinSampleRateHzOrientation = 12.5f;
+const float kMaxSampleRateHzOrientation = 200.0f;
+
+#define MINDELAY(x) ((int32_t)ceil(1.0E6f/(x)))
+
+#ifdef DIRECT_REPORT_ENABLED
+constexpr uint32_t kDirectReportFlagAccel = (
+        // support up to rate level fast (nominal 200Hz);
+        (SENSOR_DIRECT_RATE_FAST << SENSOR_FLAG_SHIFT_DIRECT_REPORT)
+        // support ashmem and gralloc direct channel
+        | SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM
+        | SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC);
+constexpr uint32_t kDirectReportFlagGyro = (
+        // support up to rate level fast (nominal 200Hz);
+        (SENSOR_DIRECT_RATE_FAST << SENSOR_FLAG_SHIFT_DIRECT_REPORT)
+        // support ashmem and gralloc direct channel
+        | SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM
+        | SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC);
+constexpr uint32_t kDirectReportFlagMag = (
+        // support up to rate level normal (nominal 50Hz);
+        (SENSOR_DIRECT_RATE_NORMAL << SENSOR_FLAG_SHIFT_DIRECT_REPORT)
+        // support ashmem and gralloc direct channel
+        | SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM
+        | SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC);
+#else
+constexpr uint32_t kDirectReportFlagAccel = 0;
+constexpr uint32_t kDirectReportFlagGyro = 0;
+constexpr uint32_t kDirectReportFlagMag = 0;
+#endif
+
+/*
+ * The following max count is determined by the total number of blocks
+ * avaliable in the shared nanohub buffer and number of samples each type of
+ * event can hold within a buffer block.
+ * For argonkey's case, there are 193 blocks in the shared sensor buffer and
+ * each block can hold 30 OneAxis Samples, 15 ThreeAxis Samples or 24
+ * RawThreeAxis Samples.
+ */
+#ifdef HAVE_VL53L0X_DRIVER
+const int kMaxOneAxisEventCount = 193*30;
+const int kMaxThreeAxisEventCount = 193*15;
+const int kMaxRawThreeAxisEventCount = 193*24;
+#else
+const int kMaxOneAxisEventCount = 183*30;
+const int kMaxThreeAxisEventCount = 183*15;
+const int kMaxRawThreeAxisEventCount = 183*24;
+#endif
+
+const int kMinFifoReservedEventCount = 20;
+
+extern const sensor_t kSensorList[] = {
+#ifdef HAVE_VL53L0X_DRIVER
+    {
+        "VL53L0X Proximity Sensor",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_PROXIMITY,
+        SENSOR_TYPE_PROXIMITY,
+        5.0f,                                          // maxRange (cm)
+        1.0f,                                          // resolution (cm)
+        0.0f,                                          // XXX power
+        MINDELAY(kMaxSampleRateHzProximity),           // minDelay
+        300,                                           // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_PROXIMITY,
+        "",                                            // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzProximity),    // maxDelay
+        SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+#endif
+    {
+        "ILS29034 Light Sensor",
+        "Intersil",
+        kVersion,
+        COMMS_SENSOR_LIGHT,
+        SENSOR_TYPE_LIGHT,
+        43000.0f,                                  // maxRange (lx)
+        10.0f,                                     // XXX resolution (lx)
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzLight),           // minDelay
+        kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                     // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_LIGHT,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzLight),    // maxDelay
+        SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+    {
+        "LSM6DSL accelerometer",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_ACCEL,
+        SENSOR_TYPE_ACCELEROMETER,
+        GRAVITY_EARTH * kAccelRangeG,              // maxRange
+        kScaleAccel,                               // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzAccel),           // minDelay
+        3000,                                      // XXX fifoReservedEventCount
+        kMaxRawThreeAxisEventCount,                // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ACCELEROMETER,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzAccel),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagAccel,
+        { NULL, NULL }
+    },
+    {
+        "LSM6DSL accelerometer (uncalibrated)",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_ACCEL_UNCALIBRATED,
+        SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED,
+        GRAVITY_EARTH * kAccelRangeG,              // maxRange
+        kScaleAccel,                               // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzAccel),           // minDelay
+        3000,                                      // XXX fifoReservedEventCount
+        kMaxRawThreeAxisEventCount,                // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ACCELEROMETER_UNCALIBRATED,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzAccel),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagAccel,
+        { NULL, NULL }
+    },
+    {
+        "LSM6DSL gyroscope",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_GYRO,
+        SENSOR_TYPE_GYROSCOPE,
+        2000.0f * M_PI / 180.0f,                   // maxRange
+        0.07f * M_PI / 180.0f,                     // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzGyro),            // minDelay
+        kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GYROSCOPE,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzGyro),     // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagGyro,
+        { NULL, NULL }
+    },
+    {
+        "LSM6DSL gyroscope (uncalibrated)",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_GYRO_UNCALIBRATED,
+        SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
+        2000.0f * M_PI / 180.0f,                   // maxRange
+        0.07f * M_PI / 180.0f,                     // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzGyro),            // minDelay
+        kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzGyro),     // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagGyro,
+        { NULL, NULL }
+    },
+    {
+        "LIS2MDL magnetometer",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_MAG,
+        SENSOR_TYPE_MAGNETIC_FIELD,
+        1300.0f,                                   // XXX maxRange
+        kScaleMag,                                 // XXX resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzMag),             // minDelay
+        600,                                       // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_MAGNETIC_FIELD,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzMag),      // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagMag,
+        { NULL, NULL }
+    },
+    {
+        "LIS2MDL magnetometer (uncalibrated)",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_MAG_UNCALIBRATED,
+        SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+        1300.0f,                                        // XXX maxRange
+        kScaleMag,                                      // XXX resolution
+        0.0f,                                           // XXX power
+        MINDELAY(kMaxSampleRateHzMag),                  // minDelay
+        600,                                            // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                        // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+        "",                                             // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzMag),           // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagMag,
+        { NULL, NULL }
+    },
+    {
+        "LPS22HB pressure",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_PRESSURE,
+        SENSOR_TYPE_PRESSURE,
+        1100.0f,                                      // maxRange (hPa)
+        0.005f,                                       // resolution (hPa)
+        0.0f,                                         // XXX power
+        MINDELAY(kMaxSampleRateHzPressure),           // minDelay
+        300,                                          // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                        // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_PRESSURE,
+        "",                                           // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzPressure),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "LPS22HB temperature",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_AMBIENT_TEMPERATURE,
+        SENSOR_TYPE_AMBIENT_TEMPERATURE,
+        85.0f,                                           // maxRange (degC)
+        0.01,                                            // resolution (degC)
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzTemperature),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                           // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzTemperature),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "HTS221 humidity",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_HUMIDITY,
+        SENSOR_TYPE_RELATIVE_HUMIDITY,
+        100.0f,                                       // maxRange (%)
+        0.001f,                                       // resolution (%)
+        0.0f,                                         // XXX power
+        MINDELAY(kMaxSampleRateHzHumidity),           // minDelay
+        300,                                          // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                        // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_RELATIVE_HUMIDITY,
+        "",                                           // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzHumidity),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Orientation",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_ORIENTATION,
+        SENSOR_TYPE_ORIENTATION,
+        360.0f,                                          // maxRange (deg)
+        1.0f,                                            // XXX resolution (deg)
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ORIENTATION,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "LSM6DSL Step detector",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_STEP_DETECTOR,
+        SENSOR_TYPE_STEP_DETECTOR,
+        1.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.0f,                                   // XXX power
+        0,                                      // minDelay
+        100,                                    // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_STEP_DETECTOR,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_SPECIAL_REPORTING_MODE,
+        { NULL, NULL }
+    },
+    {
+        "LSM6DSL Step counter",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_STEP_COUNTER,
+        SENSOR_TYPE_STEP_COUNTER,
+        65535.0f,                               // XXX maxRange
+        1.0f,                                   // resolution
+        0.0f,                                   // XXX power
+        0,                                      // minDelay
+        kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_STEP_COUNTER,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+    {
+        "LSM6DSL Significant motion",
+        "STMicroelectronics",
+        kVersion,
+        COMMS_SENSOR_SIGNIFICANT_MOTION,
+        SENSOR_TYPE_SIGNIFICANT_MOTION,
+        1.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.0f,                                   // XXX power
+        -1,                                     // minDelay
+        0,                                      // XXX fifoReservedEventCount
+        0,                                      // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_SIGNIFICANT_MOTION,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ONE_SHOT_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Gravity",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_GRAVITY,
+        SENSOR_TYPE_GRAVITY,
+        1000.0f,                                         // maxRange
+        1.0f,                                            // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GRAVITY,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Linear Acceleration",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_LINEAR_ACCEL,
+        SENSOR_TYPE_LINEAR_ACCELERATION,
+        1000.0f,                                         // maxRange
+        1.0f,                                            // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_LINEAR_ACCELERATION,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Rotation Vector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_ROTATION_VECTOR,
+        SENSOR_TYPE_ROTATION_VECTOR,
+        1.0f,                                            // maxRange
+        0.001f,                                          // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ROTATION_VECTOR,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Geomagnetic Rotation Vector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_GEO_MAG,
+        SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
+        1.0f,                                            // maxRange
+        0.001f,                                          // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Game Rotation Vector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_GAME_ROTATION_VECTOR,
+        SENSOR_TYPE_GAME_ROTATION_VECTOR,
+        1.0f,                                            // maxRange
+        0.001f,                                          // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        300,                                             // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Tilt Detector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_TILT,
+        SENSOR_TYPE_TILT_DETECTOR,
+        1.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.0f,                                   // XXX power
+        0,                                      // minDelay
+        kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_TILT_DETECTOR,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_SPECIAL_REPORTING_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Device Orientation",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_WINDOW_ORIENTATION,
+        SENSOR_TYPE_DEVICE_ORIENTATION,
+        3.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.1f,                                   // XXX power
+        0,                                      // minDelay
+        kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_DEVICE_ORIENTATION,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+};
+
+extern const size_t kSensorCount = sizeof(kSensorList) / sizeof(sensor_t);
diff --git a/sensorhal/sensorlist_neonkey.cpp b/sensorhal/sensorlist_neonkey.cpp
new file mode 100644
index 0000000..a381342
--- /dev/null
+++ b/sensorhal/sensorlist_neonkey.cpp
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sensorlist.h"
+
+#include <math.h>
+
+#include "hubdefs.h"
+
+using namespace android;
+
+const int kVersion = 1;
+
+const float kMinSampleRateHzAccel = 6.250f;
+const float kMaxSampleRateHzAccel = 400.0f;
+const float kAccelRangeG = 8.0f;
+extern const float kScaleAccel = (kAccelRangeG * 9.81f / 32768.0f);
+
+const float kMinSampleRateHzGyro = 6.250f;
+const float kMaxSampleRateHzGyro = 400.0f;
+
+const float kMinSampleRateHzMag = 3.125f;
+const float kMaxSampleRateHzMag = 50.0f;
+extern const float kScaleMag = 0.15f;
+
+const float kMinSampleRateHzPolling = 0.1f;
+const float kMaxSampleRateHzPolling = 25.0f;
+
+const float kMinSampleRateHzPressure = 0.1f;
+const float kMaxSampleRateHzPressure = 10.0f;
+
+const float kMinSampleRateHzTemperature = kMinSampleRateHzPolling;
+const float kMaxSampleRateHzTemperature = kMaxSampleRateHzPolling;
+
+const float kMinSampleRateHzHumidity = kMinSampleRateHzPolling;
+const float kMaxSampleRateHzHumidity = kMaxSampleRateHzPolling;
+
+const float kMinSampleRateHzProximity = kMinSampleRateHzPolling;
+const float kMaxSampleRateHzProximity = 5.0;
+
+const float kMinSampleRateHzLight = kMinSampleRateHzPolling;
+const float kMaxSampleRateHzLight = 5.0;
+
+const float kMinSampleRateHzOrientation = 12.5f;
+const float kMaxSampleRateHzOrientation = 200.0f;
+
+#define MINDELAY(x) ((int32_t)ceil(1.0E6f/(x)))
+
+#ifdef DIRECT_REPORT_ENABLED
+constexpr uint32_t kDirectReportFlagAccel = (
+        // support up to rate level fast (nominal 200Hz);
+        (SENSOR_DIRECT_RATE_FAST << SENSOR_FLAG_SHIFT_DIRECT_REPORT)
+        // support ashmem and gralloc direct channel
+        | SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM
+        | SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC);
+constexpr uint32_t kDirectReportFlagGyro = (
+        // support up to rate level fast (nominal 200Hz);
+        (SENSOR_DIRECT_RATE_FAST << SENSOR_FLAG_SHIFT_DIRECT_REPORT)
+        // support ashmem and gralloc direct channel
+        | SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM
+        | SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC);
+constexpr uint32_t kDirectReportFlagMag = (
+        // support up to rate level normal (nominal 50Hz);
+        (SENSOR_DIRECT_RATE_NORMAL << SENSOR_FLAG_SHIFT_DIRECT_REPORT)
+        // support ashmem and gralloc direct channel
+        | SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM
+        | SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC);
+#else
+constexpr uint32_t kDirectReportFlagAccel = 0;
+constexpr uint32_t kDirectReportFlagGyro = 0;
+constexpr uint32_t kDirectReportFlagMag = 0;
+#endif
+
+/*
+ * The following max count is determined by the total number of blocks
+ * avaliable in the shared nanohub buffer and number of samples each type of
+ * event can hold within a buffer block.
+ * For neonkey's case, there are 227 blocks in the shared sensor buffer and
+ * each block can hold 30 OneAxis Samples, 15 ThreeAxis Samples or 24
+ * RawThreeAxis Samples.
+ */
+const int kMaxOneAxisEventCount = 227*30;
+const int kMaxThreeAxisEventCount = 227*15;
+const int kMaxRawThreeAxisEventCount = 227*24;
+
+const int kMinFifoReservedEventCount = 20;
+
+const char SENSOR_STRING_TYPE_INTERNAL_TEMPERATURE[] =
+    "com.google.sensor.internal_temperature";
+const char SENSOR_STRING_TYPE_DOUBLE_TAP[] =
+    "com.google.sensor.double_tap";
+
+extern const sensor_t kSensorList[] = {
+    {
+        "RPR0521 Proximity Sensor",
+        "Rohm",
+        kVersion,
+        COMMS_SENSOR_PROXIMITY,
+        SENSOR_TYPE_PROXIMITY,
+        5.0f,                                          // maxRange (cm)
+        1.0f,                                          // resolution (cm)
+        0.0f,                                          // XXX power
+        MINDELAY(kMaxSampleRateHzProximity),           // minDelay
+        300,                                           // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_PROXIMITY,
+        "",                                            // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzProximity),    // maxDelay
+        SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+    {
+        "RPR0521 Light Sensor",
+        "Rohm",
+        kVersion,
+        COMMS_SENSOR_LIGHT,
+        SENSOR_TYPE_LIGHT,
+        43000.0f,                                  // maxRange (lx)
+        10.0f,                                     // XXX resolution (lx)
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzLight),           // minDelay
+        kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                     // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_LIGHT,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzLight),    // maxDelay
+        SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+    {
+        "BMI160 accelerometer",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_ACCEL,
+        SENSOR_TYPE_ACCELEROMETER,
+        GRAVITY_EARTH * kAccelRangeG,              // maxRange
+        kScaleAccel,                               // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzAccel),           // minDelay
+        3000,                                      // XXX fifoReservedEventCount
+        kMaxRawThreeAxisEventCount,                // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ACCELEROMETER,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzAccel),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagAccel,
+        { NULL, NULL }
+    },
+    {
+        "BMI160 accelerometer (uncalibrated)",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_ACCEL_UNCALIBRATED,
+        SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED,
+        GRAVITY_EARTH * kAccelRangeG,              // maxRange
+        kScaleAccel,                               // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzAccel),           // minDelay
+        3000,                                      // XXX fifoReservedEventCount
+        kMaxRawThreeAxisEventCount,                // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ACCELEROMETER_UNCALIBRATED,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzAccel),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagAccel,
+        { NULL, NULL }
+    },
+    {
+        "BMI160 gyroscope",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_GYRO,
+        SENSOR_TYPE_GYROSCOPE,
+        1000.0f * M_PI / 180.0f,                   // maxRange
+        1000.0f * M_PI / (180.0f * 32768.0f),      // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzGyro),            // minDelay
+        kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GYROSCOPE,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzGyro),     // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagGyro,
+        { NULL, NULL }
+    },
+    {
+        "BMI160 gyroscope (uncalibrated)",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_GYRO_UNCALIBRATED,
+        SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
+        1000.0f * M_PI / 180.0f,                   // maxRange
+        1000.0f * M_PI / (180.0f * 32768.0f),      // resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzGyro),            // minDelay
+        kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzGyro),     // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagGyro,
+        { NULL, NULL }
+    },
+    {
+        "BMM150 magnetometer",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_MAG,
+        SENSOR_TYPE_MAGNETIC_FIELD,
+        1300.0f,                                   // XXX maxRange
+        kScaleMag,                                 // XXX resolution
+        0.0f,                                      // XXX power
+        MINDELAY(kMaxSampleRateHzMag),             // minDelay
+        600,                                       // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_MAGNETIC_FIELD,
+        "",                                        // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzMag),      // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagMag,
+        { NULL, NULL }
+    },
+    {
+        "BMM150 magnetometer (uncalibrated)",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_MAG_UNCALIBRATED,
+        SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+        1300.0f,                                        // XXX maxRange
+        kScaleMag,                                      // XXX resolution
+        0.0f,                                           // XXX power
+        MINDELAY(kMaxSampleRateHzMag),                  // minDelay
+        600,                                            // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                        // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+        "",                                             // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzMag),           // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE | kDirectReportFlagMag,
+        { NULL, NULL }
+    },
+    {
+        "BMP280 pressure",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_PRESSURE,
+        SENSOR_TYPE_PRESSURE,
+        1100.0f,                                      // maxRange (hPa)
+        0.005f,                                       // resolution (hPa)
+        0.0f,                                         // XXX power
+        MINDELAY(kMaxSampleRateHzPressure),           // minDelay
+        300,                                          // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                        // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_PRESSURE,
+        "",                                           // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzPressure),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "BMP280 temperature",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_TEMPERATURE,
+        SENSOR_TYPE_INTERNAL_TEMPERATURE,
+        85.0f,                                           // maxRange (degC)
+        0.01,                                            // resolution (degC)
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzTemperature),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                           // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_INTERNAL_TEMPERATURE,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzTemperature),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "SI7034-A10 humidity",
+        "Silicon Labs",
+        kVersion,
+        COMMS_SENSOR_HUMIDITY,
+        SENSOR_TYPE_RELATIVE_HUMIDITY,
+        100.0f,                                       // maxRange (%)
+        0.001f,                                       // resolution (%)
+        0.0f,                                         // XXX power
+        MINDELAY(kMaxSampleRateHzHumidity),           // minDelay
+        300,                                          // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                        // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_RELATIVE_HUMIDITY,
+        "",                                           // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzHumidity),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "SI7034-A10 ambient temperature",
+        "Silicon Labs",
+        kVersion,
+        COMMS_SENSOR_AMBIENT_TEMPERATURE,
+        SENSOR_TYPE_AMBIENT_TEMPERATURE,
+        125.0f,                                          // maxRange (degC)
+        0.001f,                                          // resolution (degC)
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzTemperature),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                           // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzTemperature),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Orientation",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_ORIENTATION,
+        SENSOR_TYPE_ORIENTATION,
+        360.0f,                                          // maxRange (deg)
+        1.0f,                                            // XXX resolution (deg)
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ORIENTATION,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "BMI160 Step detector",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_STEP_DETECTOR,
+        SENSOR_TYPE_STEP_DETECTOR,
+        1.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.0f,                                   // XXX power
+        0,                                      // minDelay
+        100,                                    // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_STEP_DETECTOR,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_SPECIAL_REPORTING_MODE,
+        { NULL, NULL }
+    },
+    {
+        "BMI160 Step counter",
+        "Bosch",
+        kVersion,
+        COMMS_SENSOR_STEP_COUNTER,
+        SENSOR_TYPE_STEP_COUNTER,
+        1.0f,                                   // XXX maxRange
+        1.0f,                                   // resolution
+        0.0f,                                   // XXX power
+        0,                                      // minDelay
+        kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_STEP_COUNTER,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Gravity",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_GRAVITY,
+        SENSOR_TYPE_GRAVITY,
+        1000.0f,                                         // maxRange
+        1.0f,                                            // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GRAVITY,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Linear Acceleration",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_LINEAR_ACCEL,
+        SENSOR_TYPE_LINEAR_ACCELERATION,
+        1000.0f,                                         // maxRange
+        1.0f,                                            // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_LINEAR_ACCELERATION,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Rotation Vector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_ROTATION_VECTOR,
+        SENSOR_TYPE_ROTATION_VECTOR,
+        1.0f,                                            // maxRange
+        0.001f,                                          // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_ROTATION_VECTOR,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Geomagnetic Rotation Vector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_GEO_MAG,
+        SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
+        1.0f,                                            // maxRange
+        0.001,                                           // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Game Rotation Vector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_GAME_ROTATION_VECTOR,
+        SENSOR_TYPE_GAME_ROTATION_VECTOR,
+        1.0f,                                            // maxRange
+        0.001f,                                          // XXX resolution
+        0.0f,                                            // XXX power
+        MINDELAY(kMaxSampleRateHzOrientation),           // minDelay
+        300,                                             // XXX fifoReservedEventCount
+        kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR,
+        "",                                              // requiredPermission
+        (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
+        SENSOR_FLAG_CONTINUOUS_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Tilt Detector",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_TILT,
+        SENSOR_TYPE_TILT_DETECTOR,
+        1.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.0f,                                   // XXX power
+        0,                                      // minDelay
+        kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_TILT_DETECTOR,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_SPECIAL_REPORTING_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Double Tap",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_DOUBLE_TAP,
+        SENSOR_TYPE_DOUBLE_TAP,
+        1.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.1f,                                   // XXX power
+        0,                                      // minDelay
+        kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_DOUBLE_TAP,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_SPECIAL_REPORTING_MODE,
+        { NULL, NULL }
+    },
+    {
+        "Device Orientation",
+        "Google",
+        kVersion,
+        COMMS_SENSOR_WINDOW_ORIENTATION,
+        SENSOR_TYPE_DEVICE_ORIENTATION,
+        3.0f,                                   // maxRange
+        1.0f,                                   // XXX resolution
+        0.1f,                                   // XXX power
+        0,                                      // minDelay
+        kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
+        kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
+        SENSOR_STRING_TYPE_DEVICE_ORIENTATION,
+        "",                                     // requiredPermission
+        0,                                      // maxDelay
+        SENSOR_FLAG_ON_CHANGE_MODE,
+        { NULL, NULL }
+    },
+};
+
+extern const size_t kSensorCount = sizeof(kSensorList) / sizeof(sensor_t);
diff --git a/sepolicy/file.te b/sepolicy/file.te
new file mode 100644
index 0000000..ce6faad
--- /dev/null
+++ b/sepolicy/file.te
@@ -0,0 +1,6 @@
+# /data
+type nanohub_lock_file, file_type, data_file_type;
+type sensor_vendor_data_file, file_type, data_file_type, mlstrustedobject;
+
+# /sys
+type sysfs_nanoapp_cmd, sysfs_type, fs_type;
diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts
index 79c0727..c5edebb 100644
--- a/sepolicy/file_contexts
+++ b/sepolicy/file_contexts
@@ -4,10 +4,18 @@
 /dev/ttyFIQ0           u:object_r:console_device:s0
 /dev/mali              u:object_r:gpu_device:s0
 /dev/mali0             u:object_r:gpu_device:s0
+/dev/nanohub           u:object_r:sensors_device:s0
+/dev/nanohub_comms     u:object_r:sensors_device:s0
 /dev/dri/card0         u:object_r:gpu_device:s0
 /dev/hci_tty           u:object_r:hci_attach_dev:s0
 /dev/ttyAMA1           u:object_r:hci_attach_dev:s0
 /dev/ttyAMA4           u:object_r:hci_attach_dev:s0
 /dev/hifi_misc         u:object_r:audio_device:s0
-/system/vendor/bin/uim u:object_r:hci_attach_exec:s0
-/system/vendor/bin/hw/android\.hardware\.bluetooth@1\.0-service\.hikey      u:object_r:hal_bluetooth_hikey_exec:s0
+
+# files in /vendor
+/(vendor|system/vendor)/bin/uim  u:object_r:hci_attach_exec:s0
+/(vendor|system/vendor)/bin/hw/android\.hardware\.bluetooth@1\.0-service\.hikey      u:object_r:hal_bluetooth_hikey_exec:s0
+/(vendor|system/vendor)/bin/nanoapp_cmd  u:object_r:nanoapp_cmd_exec:s0
+
+# /data
+/data/vendor/sensor(/.*)?        u:object_r:sensor_vendor_data_file:s0
diff --git a/sepolicy/genfs_contexts b/sepolicy/genfs_contexts
new file mode 100644
index 0000000..fbea22a
--- /dev/null
+++ b/sepolicy/genfs_contexts
@@ -0,0 +1,2 @@
+# sysfs
+genfscon sysfs /devices/virtual/nanohub/nanohub       u:object_r:sysfs_nanoapp_cmd:s0
diff --git a/sepolicy/hal_contexthub.te b/sepolicy/hal_contexthub.te
new file mode 100644
index 0000000..2788b24
--- /dev/null
+++ b/sepolicy/hal_contexthub.te
@@ -0,0 +1,5 @@
+allow hal_contexthub sensors_device:chr_file rw_file_perms;
+
+allow hal_contexthub sensor_vendor_data_file:dir create_dir_perms;
+allow hal_contexthub sensor_vendor_data_file:file create_file_perms;
+allow hal_contexthub nanohub_lock_file:file create_file_perms;
diff --git a/sepolicy/hal_sensors.te b/sepolicy/hal_sensors.te
new file mode 100644
index 0000000..885902a
--- /dev/null
+++ b/sepolicy/hal_sensors.te
@@ -0,0 +1,22 @@
+#Allow access to nanohub device
+allow hal_sensors sensors_device:chr_file rw_file_perms;
+
+# Allow acess to uinput for lidstate determination
+allow hal_sensors uhid_device:chr_file rw_file_perms;
+
+# Allow access to saved settings file and nanohub_lock dir/file
+allow hal_sensors sensor_vendor_data_file:dir create_dir_perms;
+allow hal_sensors sensor_vendor_data_file:file create_file_perms;
+
+# Allow access to sensor properties
+set_prop(hal_sensors, sensors_prop)
+
+# Allow access to gralloc shared memory (ion), for sensor direct report
+allow hal_sensors ion_device:chr_file { open read ioctl };
+allow hal_sensors hal_graphics_allocator:fd use;
+
+# allow sensor hal to call scheduling policy service in system server
+allow hal_sensors_default system_server:binder call;
+
+# allow access to detect change in /dev folder
+allow hal_sensors_default device:dir { open read };
diff --git a/sepolicy/nanoapp_cmd.te b/sepolicy/nanoapp_cmd.te
new file mode 100644
index 0000000..c4f5b3e
--- /dev/null
+++ b/sepolicy/nanoapp_cmd.te
@@ -0,0 +1,8 @@
+type nanoapp_cmd, domain;
+type nanoapp_cmd_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(nanoapp_cmd)
+
+allow nanoapp_cmd sensors_device:chr_file rw_file_perms;
+allow nanoapp_cmd sysfs_nanoapp_cmd:dir search;
+allow nanoapp_cmd sysfs_nanoapp_cmd:file rw_file_perms;
diff --git a/sepolicy/property.te b/sepolicy/property.te
new file mode 100644
index 0000000..93e029d
--- /dev/null
+++ b/sepolicy/property.te
@@ -0,0 +1 @@
+type sensors_prop, property_type;
diff --git a/sepolicy/property_contexts b/sepolicy/property_contexts
new file mode 100644
index 0000000..3a4bde3
--- /dev/null
+++ b/sepolicy/property_contexts
@@ -0,0 +1 @@
+sensors.                   u:object_r:sensors_prop:s0
diff --git a/ueventd.common.rc b/ueventd.common.rc
index 3cc77cf..0a3c7e4 100644
--- a/ueventd.common.rc
+++ b/ueventd.common.rc
@@ -6,4 +6,6 @@
 /dev/ttyAMA4     0660 bluetooth bluetooth
 /dev/mali        0666 system graphics
 /dev/mali0       0666 system graphics
+/dev/nanohub              0660   system     system
+/dev/nanohub_comms        0660   system     system
 /dev/hifi_misc   0666 system audio