sensor HAL v3

Bug: 32021636
Test: no
Change-Id: I7a4c5c47f8621209daef5af4d0dcbb806a236e41
diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp
new file mode 100644
index 0000000..32ee049
--- /dev/null
+++ b/sensors/1.0/Android.bp
@@ -0,0 +1,46 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.sensors@1.0_genc++",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.sensors@1.0",
+    srcs: [
+        "types.hal",
+        "ISensors.hal",
+    ],
+    out: [
+        "android/hardware/sensors/1.0/types.cpp",
+        "android/hardware/sensors/1.0/SensorsAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.sensors@1.0_genc++_headers",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.sensors@1.0",
+    srcs: [
+        "types.hal",
+        "ISensors.hal",
+    ],
+    out: [
+        "android/hardware/sensors/1.0/types.h",
+        "android/hardware/sensors/1.0/ISensors.h",
+        "android/hardware/sensors/1.0/IHwSensors.h",
+        "android/hardware/sensors/1.0/BnSensors.h",
+        "android/hardware/sensors/1.0/BpSensors.h",
+        "android/hardware/sensors/1.0/BsSensors.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.sensors@1.0",
+    generated_sources: ["android.hardware.sensors@1.0_genc++"],
+    generated_headers: ["android.hardware.sensors@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.sensors@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "libcutils",
+    ],
+}
diff --git a/sensors/1.0/ISensors.hal b/sensors/1.0/ISensors.hal
new file mode 100644
index 0000000..adacfe0
--- /dev/null
+++ b/sensors/1.0/ISensors.hal
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+package android.hardware.sensors@1.0;
+
+interface ISensors {
+    /**
+     * Enumerate all available (static) sensors.
+     */
+    getSensorsList() generates (vec<SensorInfo> list);
+
+    /**
+     *  Place the module in a specific mode. The following modes are defined
+     *
+     *  SENSOR_HAL_NORMAL_MODE - Normal operation. Default state of the module.
+     *
+     *  SENSOR_HAL_DATA_INJECTION_MODE - Loopback mode.
+     *    Data is injected for the supported sensors by the sensor service in
+     *    this mode.
+     *
+     * @return OK on success
+     *         BAD_VALUE if requested mode is not supported
+     *         PERMISSION_DENIED if operation is not allowed
+     */
+    setOperationMode(OperationMode mode) generates (Result result);
+
+    /* Activate/de-activate one sensor.
+     *
+     * sensorHandle is the handle of the sensor to change.
+     * enabled set to true to enable, or false to disable the sensor.
+     *
+     * After sensor de-activation, existing sensor events that have not
+     * been picked up by poll() should be abandoned immediately so that
+     * subsequent activation will not get stale sensor events (events
+     * that are generated prior to the latter activation).
+     *
+     * Returns OK on success, BAD_VALUE if sensorHandle is invalid.
+     */
+    activate(int32_t sensorHandle, bool enabled) generates (Result result);
+
+    /**
+     * Set the sampling period in nanoseconds for a given sensor.
+     * If samplingPeriodNs > maxDelay it will be truncated to
+     * maxDelay and if samplingPeriodNs < minDelay it will be
+     * replaced by minDelay.
+     *
+     * Returns OK on success, BAD_VALUE if sensorHandle is invalid.
+     */
+    setDelay(int32_t sensorHandle, int64_t samplingPeriodNs)
+        generates (Result result);
+
+    /**
+     * Generate a vector of sensor events containing at most "maxCount"
+     * entries.
+     *
+     * Additionally a vector of SensorInfos is returned for any dynamic sensors
+     * connected as notified by returned events of type DYNAMIC_SENSOR_META.
+     *
+     * This function should block if there is no sensor event
+     * available when being called.
+     *
+     * Returns OK on success or BAD_VALUE if maxCount <= 0.
+     */
+    poll(int32_t maxCount)
+        generates (
+                Result result,
+                vec<Event> data,
+                vec<SensorInfo> dynamicSensorsAdded);
+
+    /*
+     * Sets a sensor’s parameters, including sampling frequency and maximum
+     * report latency. This function can be called while the sensor is
+     * activated, in which case it must not cause any sensor measurements to
+     * be lost: transitioning from one sampling rate to the other cannot cause
+     * lost events, nor can transitioning from a high maximum report latency to
+     * a low maximum report latency.
+     * See the Batching sensor results page for details:
+     * http://source.android.com/devices/sensors/batching.html
+     *
+     * Returns OK on success, BAD_VALUE if any parameters are invalid.
+     */
+    batch(int32_t sensorHandle,
+          int32_t flags,
+          int64_t samplingPeriodNs,
+          int64_t maxReportLatencyNs) generates (Result result);
+
+    /*
+     * Flush adds a FLUSH_COMPLETE metadata event to the end of the "batch mode"
+     * FIFO for the specified sensor and flushes the FIFO.
+     * If the FIFO is empty or if the sensor doesn't support batching
+     * (FIFO size zero), it should return SUCCESS along with a trivial
+     * FLUSH_COMPLETE event added to the event stream.
+     * This applies to all sensors other than one-shot sensors.
+     * If the sensor is a one-shot sensor, flush must return BAD_VALUE and not
+     * generate any flush complete metadata.
+     * If the sensor is not active at the time flush() is called, flush() should
+     * return BAD_VALUE.
+     * Returns OK on success and BAD_VALUE if sensorHandle is invalid.
+     */
+    flush(int32_t sensorHandle) generates (Result result);
+
+    /*
+     * Inject a single sensor sample to this device.
+     * data points to the sensor event to be injected
+     * Returns OK on success
+     *         PERMISSION_DENIED if operation is not allowed
+     *         INVALID_OPERATION, if this functionality is unsupported
+     *         BAD_VALUE if sensor event cannot be injected
+     */
+    injectSensorData(Event event) generates (Result result);
+};
diff --git a/sensors/1.0/default/Android.bp b/sensors/1.0/default/Android.bp
new file mode 100644
index 0000000..d454cdb
--- /dev/null
+++ b/sensors/1.0/default/Android.bp
@@ -0,0 +1,38 @@
+cc_library_shared {
+    name: "android.hardware.sensors@1.0-impl",
+    relative_install_path: "hw",
+    srcs: ["Sensors.cpp"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libhardware",
+        "libhwbinder",
+        "libbase",
+        "libcutils",
+        "libutils",
+        "libhidl",
+        "android.hardware.sensors@1.0",
+    ],
+    static_libs: [
+        "android.hardware.sensors@1.0-convert",
+    ],
+}
+
+cc_library_static {
+    name: "android.hardware.sensors@1.0-convert",
+    srcs: ["convert.cpp"],
+    export_include_dirs: ["include"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libhardware",
+        "libhwbinder",
+        "libbase",
+        "libcutils",
+        "libutils",
+        "libhidl",
+        "android.hardware.sensors@1.0",
+    ],
+}
+
+
diff --git a/sensors/1.0/default/Android.mk b/sensors/1.0/default/Android.mk
new file mode 100644
index 0000000..4f418cb
--- /dev/null
+++ b/sensors/1.0/default/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.sensors@1.0-service
+LOCAL_INIT_RC := android.hardware.sensors@1.0-service.rc
+LOCAL_SRC_FILES := \
+	service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+	liblog \
+	libcutils \
+	libdl \
+	libbase \
+	libutils \
+	libhardware_legacy \
+	libhardware \
+
+LOCAL_SHARED_LIBRARIES += \
+	libhwbinder \
+	libhidl \
+	android.hardware.sensors@1.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/sensors/1.0/default/Sensors.cpp b/sensors/1.0/default/Sensors.cpp
new file mode 100644
index 0000000..ef052c3
--- /dev/null
+++ b/sensors/1.0/default/Sensors.cpp
@@ -0,0 +1,250 @@
+/*
+ * 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 "Sensors.h"
+
+#include "convert.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V1_0 {
+namespace implementation {
+
+static Result ResultFromStatus(status_t err) {
+    switch (err) {
+        case OK:
+            return Result::OK;
+        case BAD_VALUE:
+            return Result::BAD_VALUE;
+        case PERMISSION_DENIED:
+            return Result::PERMISSION_DENIED;
+        default:
+            return Result::INVALID_OPERATION;
+    }
+}
+
+Sensors::Sensors()
+    : mInitCheck(NO_INIT),
+      mSensorModule(nullptr),
+      mSensorDevice(nullptr) {
+    status_t err = hw_get_module(
+            SENSORS_HARDWARE_MODULE_ID,
+            (hw_module_t const **)&mSensorModule);
+
+    if (mSensorModule == NULL) {
+        err = UNKNOWN_ERROR;
+    }
+
+    if (err != OK) {
+        LOG(ERROR) << "Couldn't load "
+                   << SENSORS_HARDWARE_MODULE_ID
+                   << " module ("
+                   << strerror(-err)
+                   << ")";
+
+        mInitCheck = err;
+        return;
+    }
+
+    err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
+
+    if (err != OK) {
+        LOG(ERROR) << "Couldn't open device for module "
+                   << SENSORS_HARDWARE_MODULE_ID
+                   << " ("
+                   << strerror(-err)
+                   << ")";
+
+        mInitCheck = err;
+        return;
+    }
+
+    // Require all the old HAL APIs to be present except for injection, which
+    // is considered optional.
+    CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);
+
+    mInitCheck = OK;
+}
+
+status_t Sensors::initCheck() const {
+    return mInitCheck;
+}
+
+Return<void> Sensors::getSensorsList(getSensorsList_cb _aidl_cb) {
+    sensor_t const *list;
+    size_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
+
+    hidl_vec<SensorInfo> out;
+    out.resize(count);
+
+    for (size_t i = 0; i < count; ++i) {
+        const sensor_t *src = &list[i];
+        SensorInfo *dst = &out[i];
+
+        convertFromSensor(*src, dst);
+    }
+
+    _aidl_cb(out);
+
+    return Void();
+}
+
+int Sensors::getHalDeviceVersion() const {
+    if (!mSensorDevice) {
+        return -1;
+    }
+
+    return mSensorDevice->common.version;
+}
+
+Return<Result> Sensors::setOperationMode(OperationMode mode) {
+    return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode));
+}
+
+Return<Result> Sensors::activate(
+        int32_t sensor_handle, bool enabled) {
+    return ResultFromStatus(
+            mSensorDevice->activate(
+                reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
+                sensor_handle,
+                enabled));
+}
+
+Return<Result> Sensors::setDelay(
+        int32_t sensor_handle, int64_t sampling_period_ns) {
+    return ResultFromStatus(
+            mSensorDevice->setDelay(
+                reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
+                sensor_handle,
+                sampling_period_ns));
+}
+
+Return<void> Sensors::poll(int32_t maxCount, poll_cb _aidl_cb) {
+    hidl_vec<Event> out;
+    hidl_vec<SensorInfo> dynamicSensorsAdded;
+
+    if (maxCount <= 0) {
+        _aidl_cb(Result::BAD_VALUE, out, dynamicSensorsAdded);
+        return Void();
+    }
+
+    std::unique_ptr<sensors_event_t[]> data(new sensors_event_t[maxCount]);
+
+    int err = mSensorDevice->poll(
+            reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
+            data.get(),
+            maxCount);
+
+    if (err < 0) {
+        _aidl_cb(ResultFromStatus(err), out, dynamicSensorsAdded);
+        return Void();
+    }
+
+    const size_t count = (size_t)err;
+
+    for (size_t i = 0; i < count; ++i) {
+        if (data[i].type != SENSOR_TYPE_DYNAMIC_SENSOR_META) {
+            continue;
+        }
+
+        const dynamic_sensor_meta_event_t *dyn = &data[i].dynamic_sensor_meta;
+
+        if (!dyn->connected) {
+            continue;
+        }
+
+        CHECK(dyn->sensor != nullptr);
+        CHECK_EQ(dyn->sensor->handle, dyn->handle);
+
+        SensorInfo info;
+        convertFromSensor(*dyn->sensor, &info);
+
+        size_t numDynamicSensors = dynamicSensorsAdded.size();
+        dynamicSensorsAdded.resize(numDynamicSensors + 1);
+        dynamicSensorsAdded[numDynamicSensors] = info;
+    }
+
+    out.resize(count);
+    convertFromSensorEvents(err, data.get(), &out);
+
+    _aidl_cb(Result::OK, out, dynamicSensorsAdded);
+
+    return Void();
+}
+
+Return<Result> Sensors::batch(
+        int32_t sensor_handle,
+        int32_t flags,
+        int64_t sampling_period_ns,
+        int64_t max_report_latency_ns) {
+    return ResultFromStatus(
+            mSensorDevice->batch(
+                mSensorDevice,
+                sensor_handle,
+                flags,
+                sampling_period_ns,
+                max_report_latency_ns));
+}
+
+Return<Result> Sensors::flush(int32_t sensor_handle) {
+    return ResultFromStatus(mSensorDevice->flush(mSensorDevice, sensor_handle));
+}
+
+Return<Result> Sensors::injectSensorData(const Event& event) {
+    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
+        return Result::INVALID_OPERATION;
+    }
+
+    sensors_event_t out;
+    convertToSensorEvent(event, &out);
+
+    return ResultFromStatus(
+            mSensorDevice->inject_sensor_data(mSensorDevice, &out));
+}
+
+// static
+void Sensors::convertFromSensorEvents(
+        size_t count,
+        const sensors_event_t *srcArray,
+        hidl_vec<Event> *dstVec) {
+    for (size_t i = 0; i < count; ++i) {
+        const sensors_event_t &src = srcArray[i];
+        Event *dst = &(*dstVec)[i];
+
+        convertFromSensorEvent(src, dst);
+    }
+}
+
+ISensors *HIDL_FETCH_ISensors(const char * /* hal */) {
+    Sensors *sensors = new Sensors;
+    if (sensors->initCheck() != OK) {
+        delete sensors;
+        sensors = nullptr;
+
+        return nullptr;
+    }
+
+    return sensors;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/sensors/1.0/default/Sensors.h b/sensors/1.0/default/Sensors.h
new file mode 100644
index 0000000..f9b837d
--- /dev/null
+++ b/sensors/1.0/default/Sensors.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_SENSORS_H_
+
+#define HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_SENSORS_H_
+
+#include <android/hardware/sensors/1.0/ISensors.h>
+#include <hardware/sensors.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V1_0 {
+namespace implementation {
+
+struct Sensors : public ::android::hardware::sensors::V1_0::ISensors {
+    Sensors();
+
+    status_t initCheck() const;
+
+    Return<void> getSensorsList(getSensorsList_cb _aidl_cb) override;
+
+    Return<Result> setOperationMode(OperationMode mode) override;
+
+    Return<Result> activate(
+            int32_t sensor_handle, bool enabled) override;
+
+    Return<Result> setDelay(
+            int32_t sensor_handle, int64_t sampling_period_ns) override;
+
+    Return<void> poll(int32_t maxCount, poll_cb _hidl_cb) override;
+
+    Return<Result> batch(
+            int32_t sensor_handle,
+            int32_t flags,
+            int64_t sampling_period_ns,
+            int64_t max_report_latency_ns) override;
+
+    Return<Result> flush(int32_t sensor_handle) override;
+
+    Return<Result> injectSensorData(const Event& event) override;
+
+private:
+    status_t mInitCheck;
+    sensors_module_t *mSensorModule;
+    sensors_poll_device_1_t *mSensorDevice;
+
+    int getHalDeviceVersion() const;
+
+    static void convertFromSensorEvents(
+            size_t count, const sensors_event_t *src, hidl_vec<Event> *dst);
+
+    DISALLOW_COPY_AND_ASSIGN(Sensors);
+};
+
+extern "C" ISensors *HIDL_FETCH_ISensors(const char *name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_SENSORS_H_
diff --git a/sensors/1.0/default/android.hardware.sensors@1.0-service.rc b/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
new file mode 100644
index 0000000..2cba0fc
--- /dev/null
+++ b/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
@@ -0,0 +1,4 @@
+service sensors-hal-1-0 /system/bin/hw/android.hardware.sensors@1.0-service
+    class main
+    user system
+    group system readproc
diff --git a/sensors/1.0/default/convert.cpp b/sensors/1.0/default/convert.cpp
new file mode 100644
index 0000000..f4e1841
--- /dev/null
+++ b/sensors/1.0/default/convert.cpp
@@ -0,0 +1,346 @@
+/*
+ * 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 "include/convert.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V1_0 {
+namespace implementation {
+
+void convertFromSensor(const sensor_t &src, SensorInfo *dst) {
+    dst->name = src.name;
+    dst->vendor = src.vendor;
+    dst->version = src.version;
+    dst->sensorHandle = src.handle;
+    dst->type = (SensorType)src.type;
+    dst->maxRange = src.maxRange;
+    dst->resolution = src.resolution;
+    dst->power = src.power;
+    dst->minDelay = src.minDelay;
+    dst->fifoReservedEventCount = src.fifoReservedEventCount;
+    dst->fifoMaxEventCount = src.fifoMaxEventCount;
+    dst->typeAsString = src.stringType;
+    dst->requiredPermission = src.requiredPermission;
+    dst->maxDelay = src.maxDelay;
+    dst->flags = src.flags;
+}
+
+void convertToSensor(
+        const ::android::hardware::sensors::V1_0::SensorInfo &src,
+        sensor_t *dst) {
+    dst->name = strdup(src.name.c_str());
+    dst->vendor = strdup(src.vendor.c_str());
+    dst->version = src.version;
+    dst->handle = src.sensorHandle;
+    dst->type = (int)src.type;
+    dst->maxRange = src.maxRange;
+    dst->resolution = src.resolution;
+    dst->power = src.power;
+    dst->minDelay = src.minDelay;
+    dst->fifoReservedEventCount = src.fifoReservedEventCount;
+    dst->fifoMaxEventCount = src.fifoMaxEventCount;
+    dst->stringType = strdup(src.typeAsString.c_str());
+    dst->requiredPermission = strdup(src.requiredPermission.c_str());
+    dst->maxDelay = src.maxDelay;
+    dst->flags = src.flags;
+    dst->reserved[0] = dst->reserved[1] = 0;
+}
+
+void convertFromSensorEvent(const sensors_event_t &src, Event *dst) {
+    typedef ::android::hardware::sensors::V1_0::SensorType SensorType;
+    typedef ::android::hardware::sensors::V1_0::MetaDataEventType MetaDataEventType;
+
+    dst->sensorHandle = src.sensor;
+    dst->sensorType = (SensorType)src.type;
+    dst->timestamp = src.timestamp;
+
+    switch (dst->sensorType) {
+        case SensorType::SENSOR_TYPE_META_DATA:
+        {
+            dst->u.meta.what = (MetaDataEventType)src.meta_data.what;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_ACCELEROMETER:
+        case SensorType::SENSOR_TYPE_GEOMAGNETIC_FIELD:
+        case SensorType::SENSOR_TYPE_ORIENTATION:
+        case SensorType::SENSOR_TYPE_GYROSCOPE:
+        case SensorType::SENSOR_TYPE_GRAVITY:
+        case SensorType::SENSOR_TYPE_LINEAR_ACCELERATION:
+        {
+            dst->u.vec3.x = src.acceleration.x;
+            dst->u.vec3.y = src.acceleration.y;
+            dst->u.vec3.z = src.acceleration.z;
+            dst->u.vec3.status = (SensorStatus)src.acceleration.status;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_ROTATION_VECTOR:
+        case SensorType::SENSOR_TYPE_GAME_ROTATION_VECTOR:
+        case SensorType::SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+        {
+            dst->u.vec4.x = src.data[0];
+            dst->u.vec4.y = src.data[1];
+            dst->u.vec4.z = src.data[2];
+            dst->u.vec4.w = src.data[3];
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+        case SensorType::SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+        {
+            dst->u.uncal.x = src.uncalibrated_gyro.x_uncalib;
+            dst->u.uncal.y = src.uncalibrated_gyro.y_uncalib;
+            dst->u.uncal.z = src.uncalibrated_gyro.z_uncalib;
+            dst->u.uncal.x_bias = src.uncalibrated_gyro.x_bias;
+            dst->u.uncal.y_bias = src.uncalibrated_gyro.y_bias;
+            dst->u.uncal.z_bias = src.uncalibrated_gyro.z_bias;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_DEVICE_ORIENTATION:
+        case SensorType::SENSOR_TYPE_LIGHT:
+        case SensorType::SENSOR_TYPE_PRESSURE:
+        case SensorType::SENSOR_TYPE_TEMPERATURE:
+        case SensorType::SENSOR_TYPE_PROXIMITY:
+        case SensorType::SENSOR_TYPE_RELATIVE_HUMIDITY:
+        case SensorType::SENSOR_TYPE_AMBIENT_TEMPERATURE:
+        case SensorType::SENSOR_TYPE_SIGNIFICANT_MOTION:
+        case SensorType::SENSOR_TYPE_STEP_DETECTOR:
+        case SensorType::SENSOR_TYPE_TILT_DETECTOR:
+        case SensorType::SENSOR_TYPE_WAKE_GESTURE:
+        case SensorType::SENSOR_TYPE_GLANCE_GESTURE:
+        case SensorType::SENSOR_TYPE_PICK_UP_GESTURE:
+        case SensorType::SENSOR_TYPE_WRIST_TILT_GESTURE:
+        case SensorType::SENSOR_TYPE_STATIONARY_DETECT:
+        case SensorType::SENSOR_TYPE_MOTION_DETECT:
+        case SensorType::SENSOR_TYPE_HEART_BEAT:
+        {
+            dst->u.scalar = src.data[0];
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_STEP_COUNTER:
+        {
+            dst->u.stepCount = src.u64.step_counter;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_HEART_RATE:
+        {
+            dst->u.heartRate.bpm = src.heart_rate.bpm;
+            dst->u.heartRate.status = (SensorStatus)src.heart_rate.status;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_POSE_6DOF:  // 15 floats
+        {
+            for (size_t i = 0; i < 15; ++i) {
+                dst->u.pose6DOF[i] = src.data[i];
+            }
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_DYNAMIC_SENSOR_META:
+        {
+            dst->u.dynamic.connected = src.dynamic_sensor_meta.connected;
+            dst->u.dynamic.sensorHandle = src.dynamic_sensor_meta.handle;
+
+            memcpy(dst->u.dynamic.uuid.data(),
+                   src.dynamic_sensor_meta.uuid,
+                   16);
+
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_ADDITIONAL_INFO:
+        {
+            ::android::hardware::sensors::V1_0::AdditionalInfo *dstInfo =
+                &dst->u.additional;
+
+            const additional_info_event_t &srcInfo = src.additional_info;
+
+            dstInfo->type =
+                (::android::hardware::sensors::V1_0::AdditionalInfoType)
+                    srcInfo.type;
+
+            dstInfo->serial = srcInfo.serial;
+
+            CHECK_EQ(sizeof(dstInfo->u), sizeof(srcInfo.data_int32));
+            memcpy(&dstInfo->u, srcInfo.data_int32, sizeof(srcInfo.data_int32));
+            break;
+        }
+
+        default:
+        {
+            CHECK_GE((int32_t)dst->sensorType,
+                     (int32_t)SensorType::SENSOR_TYPE_DEVICE_PRIVATE_BASE);
+
+            memcpy(dst->u.data.data(), src.data, 16 * sizeof(float));
+            break;
+        }
+    }
+}
+
+void convertToSensorEvent(const Event &src, sensors_event_t *dst) {
+    dst->version = sizeof(sensors_event_t);
+    dst->sensor = src.sensorHandle;
+    dst->type = (int32_t)src.sensorType;
+    dst->reserved0 = 0;
+    dst->timestamp = src.timestamp;
+    dst->flags = 0;
+    dst->reserved1[0] = dst->reserved1[1] = dst->reserved1[2] = 0;
+
+    switch (src.sensorType) {
+        case SensorType::SENSOR_TYPE_META_DATA:
+        {
+            dst->meta_data.what = (int32_t)src.u.meta.what;
+            dst->meta_data.sensor = dst->sensor;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_ACCELEROMETER:
+        case SensorType::SENSOR_TYPE_GEOMAGNETIC_FIELD:
+        case SensorType::SENSOR_TYPE_ORIENTATION:
+        case SensorType::SENSOR_TYPE_GYROSCOPE:
+        case SensorType::SENSOR_TYPE_GRAVITY:
+        case SensorType::SENSOR_TYPE_LINEAR_ACCELERATION:
+        {
+            dst->acceleration.x = src.u.vec3.x;
+            dst->acceleration.y = src.u.vec3.y;
+            dst->acceleration.z = src.u.vec3.z;
+            dst->acceleration.status = (int8_t)src.u.vec3.status;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_ROTATION_VECTOR:
+        case SensorType::SENSOR_TYPE_GAME_ROTATION_VECTOR:
+        case SensorType::SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+        {
+            dst->data[0] = src.u.vec4.x;
+            dst->data[1] = src.u.vec4.y;
+            dst->data[2] = src.u.vec4.z;
+            dst->data[3] = src.u.vec4.w;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+        case SensorType::SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+        {
+            dst->uncalibrated_gyro.x_uncalib = src.u.uncal.x;
+            dst->uncalibrated_gyro.y_uncalib = src.u.uncal.y;
+            dst->uncalibrated_gyro.z_uncalib = src.u.uncal.z;
+            dst->uncalibrated_gyro.x_bias = src.u.uncal.x_bias;
+            dst->uncalibrated_gyro.y_bias = src.u.uncal.y_bias;
+            dst->uncalibrated_gyro.z_bias = src.u.uncal.z_bias;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_DEVICE_ORIENTATION:
+        case SensorType::SENSOR_TYPE_LIGHT:
+        case SensorType::SENSOR_TYPE_PRESSURE:
+        case SensorType::SENSOR_TYPE_TEMPERATURE:
+        case SensorType::SENSOR_TYPE_PROXIMITY:
+        case SensorType::SENSOR_TYPE_RELATIVE_HUMIDITY:
+        case SensorType::SENSOR_TYPE_AMBIENT_TEMPERATURE:
+        case SensorType::SENSOR_TYPE_SIGNIFICANT_MOTION:
+        case SensorType::SENSOR_TYPE_STEP_DETECTOR:
+        case SensorType::SENSOR_TYPE_TILT_DETECTOR:
+        case SensorType::SENSOR_TYPE_WAKE_GESTURE:
+        case SensorType::SENSOR_TYPE_GLANCE_GESTURE:
+        case SensorType::SENSOR_TYPE_PICK_UP_GESTURE:
+        case SensorType::SENSOR_TYPE_WRIST_TILT_GESTURE:
+        case SensorType::SENSOR_TYPE_STATIONARY_DETECT:
+        case SensorType::SENSOR_TYPE_MOTION_DETECT:
+        case SensorType::SENSOR_TYPE_HEART_BEAT:
+        {
+            dst->data[0] = src.u.scalar;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_STEP_COUNTER:
+        {
+            dst->u64.step_counter = src.u.stepCount;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_HEART_RATE:
+        {
+            dst->heart_rate.bpm = src.u.heartRate.bpm;
+            dst->heart_rate.status = (int8_t)src.u.heartRate.status;
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_POSE_6DOF:  // 15 floats
+        {
+            for (size_t i = 0; i < 15; ++i) {
+                dst->data[i] = src.u.pose6DOF[i];
+            }
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_DYNAMIC_SENSOR_META:
+        {
+            dst->dynamic_sensor_meta.connected = src.u.dynamic.connected;
+            dst->dynamic_sensor_meta.handle = src.u.dynamic.sensorHandle;
+            dst->dynamic_sensor_meta.sensor = NULL;  // to be filled in later
+
+            memcpy(dst->dynamic_sensor_meta.uuid,
+                   src.u.dynamic.uuid.data(),
+                   16);
+
+            break;
+        }
+
+        case SensorType::SENSOR_TYPE_ADDITIONAL_INFO:
+        {
+            const ::android::hardware::sensors::V1_0::AdditionalInfo &srcInfo =
+                src.u.additional;
+
+            additional_info_event_t *dstInfo = &dst->additional_info;
+            dstInfo->type = (int32_t)srcInfo.type;
+            dstInfo->serial = srcInfo.serial;
+
+            CHECK_EQ(sizeof(srcInfo.u), sizeof(dstInfo->data_int32));
+
+            memcpy(dstInfo->data_int32,
+                   &srcInfo.u,
+                   sizeof(dstInfo->data_int32));
+
+            break;
+        }
+
+        default:
+        {
+            CHECK_GE((int32_t)src.sensorType,
+                     (int32_t)SensorType::SENSOR_TYPE_DEVICE_PRIVATE_BASE);
+
+            memcpy(dst->data, src.u.data.data(), 16 * sizeof(float));
+            break;
+        }
+    }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+
diff --git a/sensors/1.0/default/include/convert.h b/sensors/1.0/default/include/convert.h
new file mode 100644
index 0000000..d289a81
--- /dev/null
+++ b/sensors/1.0/default/include/convert.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_INCLUDE_CONVERT_H_
+
+#define HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_INCLUDE_CONVERT_H_
+
+#include <android/hardware/sensors/1.0/ISensors.h>
+#include <hardware/sensors.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V1_0 {
+namespace implementation {
+
+void convertFromSensor(const sensor_t &src, SensorInfo *dst);
+void convertToSensor(const SensorInfo &src, sensor_t *dst);
+
+void convertFromSensorEvent(const sensors_event_t &src, Event *dst);
+void convertToSensorEvent(const Event &src, sensors_event_t *dst);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_INCLUDE_CONVERT_H_
diff --git a/sensors/1.0/default/service.cpp b/sensors/1.0/default/service.cpp
new file mode 100644
index 0000000..da543ef
--- /dev/null
+++ b/sensors/1.0/default/service.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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 <android-base/logging.h>
+#include <android/hardware/sensors/1.0/ISensors.h>
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+
+int main() {
+    using android::hardware::sensors::V1_0::ISensors;
+    using android::sp;
+    using android::OK;
+    using namespace android::hardware;
+
+    LOG(INFO) << "Service is starting.";
+    sp<ISensors> sensors = ISensors::getService("sensors", true /* getStub */);
+
+    if (sensors.get() == nullptr) {
+        LOG(ERROR) << "ISensors::getService returned nullptr, exiting.";
+        return 1;
+    }
+
+    LOG(INFO) << "Default implementation using sensors is "
+              << (sensors->isRemote() ? "REMOTE" : "LOCAL");
+
+    CHECK(!sensors->isRemote());
+
+    LOG(INFO) << "Registering instance sensors.";
+    sensors->registerAsService("sensors");
+    LOG(INFO) << "Ready.";
+
+    ProcessState::self()->setThreadPoolMaxThreadCount(0);
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+
+    return 0;
+}
+
diff --git a/sensors/1.0/types.hal b/sensors/1.0/types.hal
new file mode 100644
index 0000000..ba4921c
--- /dev/null
+++ b/sensors/1.0/types.hal
@@ -0,0 +1,1064 @@
+/*
+ * 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.
+ */
+
+package android.hardware.sensors@1.0;
+
+/**
+ * Please see the Sensors section of source.android.com for an
+ * introduction to and detailed descriptions of Android sensor types:
+ * http://source.android.com/devices/sensors/index.html
+ */
+
+/* Type enumerating various result codes returned from ISensors methods */
+enum Result : int32_t {
+    OK,
+    BAD_VALUE,
+    PERMISSION_DENIED,
+    INVALID_OPERATION,
+};
+
+/*
+ * Sensor HAL modes used in setOperationMode method
+ */
+@export(name="")
+enum OperationMode : int32_t {
+    SENSOR_HAL_NORMAL_MODE              = 0,
+    SENSOR_HAL_DATA_INJECTION_MODE      = 1,
+};
+
+/*
+ * Sensor type
+ *
+ * Each sensor has a type which defines what this sensor measures and how
+ * measures are reported. See the Base sensors and Composite sensors lists
+ * for complete descriptions:
+ * http://source.android.com/devices/sensors/base_triggers.html
+ * http://source.android.com/devices/sensors/composite_sensors.html
+ *
+ * Device manufacturers (OEMs) can define their own sensor types, for
+ * their private use by applications or services provided by them. Such
+ * sensor types are specific to an OEM and can't be exposed in the SDK.
+ * These types must start at SENSOR_TYPE_DEVICE_PRIVATE_BASE.
+ *
+ * All sensors defined outside of the device private range must correspond to
+ * a type defined in this file, and must satisfy the characteristics listed in
+ * the description of the sensor type.
+ *
+ * Each sensor also has a "typeAsString".
+ *  - StringType of sensors inside of the device private range MUST be prefixed
+ *    by the sensor provider's or OEM reverse domain name. In particular, they
+ *    cannot use the "android.sensor" prefix.
+ *  - StringType of sensors outside of the device private range MUST correspond
+ *    to the one defined in this file (starting with "android.sensor").
+ *    For example, accelerometers must have
+ *      type=SENSOR_TYPE_ACCELEROMETER and
+ *      stringType=SENSOR_STRING_TYPE_ACCELEROMETER
+ *
+ * When android introduces a new sensor type that can replace an OEM-defined
+ * sensor type, the OEM must use the official sensor type and stringType on
+ * versions of the HAL that support this new official sensor type.
+ *
+ * Example (made up): Suppose Google's Glass team wants to surface a sensor
+ * detecting that Glass is on a head.
+ *  - Such a sensor is not officially supported in android KitKat
+ *  - Glass devices launching on KitKat can implement a sensor with
+ *    type = 0x10001 and stringType = "com.google.glass.onheaddetector"
+ *  - In L android release, if android decides to define
+ *    SENSOR_TYPE_ON_HEAD_DETECTOR and STRING_SENSOR_TYPE_ON_HEAD_DETECTOR,
+ *    those types should replace the Glass-team-specific types in all future
+ *    launches.
+ *  - When launching Glass on the L release, Google should now use the official
+ *    type (SENSOR_TYPE_ON_HEAD_DETECTOR) and stringType.
+ *  - This way, all applications can now use this sensor.
+ */
+
+/*
+ * Wake up sensors.
+ * Each sensor may have either or both a wake-up and a non-wake variant.
+ * When registered in batch mode, wake-up sensors will wake up the AP when
+ * their FIFOs are full or when the batch timeout expires. A separate FIFO has
+ * to be maintained for wake up sensors and non wake up sensors. The non
+ * wake-up sensors need to overwrite their FIFOs when they are full till the AP
+ * wakes up and the wake-up sensors will wake-up the AP when their FIFOs are
+ * full or when the batch timeout expires without losing events.
+ * Wake-up and non wake-up variants of each sensor can be activated at
+ * different rates independently of each other.
+ *
+ * Note: Proximity sensor and significant motion sensor which were defined in
+ * previous releases are also wake-up sensors and should be treated as such.
+ * Wake-up one-shot sensors like SIGNIFICANT_MOTION cannot be batched, hence
+ * the text about batch above doesn't apply to them. See the definitions of
+ * SENSOR_TYPE_PROXIMITY and SENSOR_TYPE_SIGNIFICANT_MOTION for more info.
+ *
+ * Set SENSOR_FLAG_WAKE_UP flag for all wake-up sensors.
+ *
+ * For example, A device can have two sensors both of SENSOR_TYPE_ACCELEROMETER
+ * and one of them can be a wake_up sensor (with SENSOR_FLAG_WAKE_UP flag set)
+ * and the other can be a regular non wake_up sensor. Both of these sensors
+ * must be activated/deactivated independently of the other.
+ */
+
+@export(name="")
+enum SensorType : int32_t {
+    /* META_DATA is a special event type used to populate the MetaData
+     * structure. It doesn't correspond to a physical sensor. Events of this
+     * type exist only inside the HAL, their primary purpose is to signal the
+     * completion of a flush request.
+     */
+    SENSOR_TYPE_META_DATA                       = 0,
+
+    /*
+     * SENSOR_TYPE_ACCELEROMETER
+     * reporting-mode: continuous
+     *
+     * All values are in SI units (m/s^2) and measure the acceleration of the
+     * device minus the force of gravity.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_ACCELEROMETER                   = 1,
+
+    /*
+     * SENSOR_TYPE_GEOMAGNETIC_FIELD
+     * reporting-mode: continuous
+     *
+     * All values are in micro-Tesla (uT) and measure the geomagnetic
+     * field in the X, Y and Z axis.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_GEOMAGNETIC_FIELD               = 2,
+
+    /*
+     * SENSOR_TYPE_ORIENTATION
+     * reporting-mode: continuous
+     *
+     * All values are angles in degrees.
+     *
+     * Orientation sensors return sensor events for all 3 axes at a constant
+     * rate defined by setDelay().
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_ORIENTATION                     = 3,
+
+    /*
+     * SENSOR_TYPE_GYROSCOPE
+     * reporting-mode: continuous
+     *
+     * All values are in radians/second and measure the rate of rotation
+     * around the X, Y and Z axis.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_GYROSCOPE                       = 4,
+
+    /*
+     * SENSOR_TYPE_LIGHT
+     * reporting-mode: on-change
+     *
+     * The light sensor value is returned in SI lux units.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    SENSOR_TYPE_LIGHT                           = 5,
+
+    /*
+     * SENSOR_TYPE_PRESSURE
+     * reporting-mode: continuous
+     *
+     * The pressure sensor return the athmospheric pressure in hectopascal (hPa)
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_PRESSURE                        = 6,
+
+    /* SENSOR_TYPE_TEMPERATURE is deprecated in the HAL */
+    SENSOR_TYPE_TEMPERATURE                     = 7,
+
+    /*
+     * SENSOR_TYPE_PROXIMITY
+     * reporting-mode: on-change
+     *
+     * The proximity sensor which turns the screen off and back on during calls
+     * is the wake-up proximity sensor. Implement wake-up proximity sensor
+     * before implementing a non wake-up proximity sensor. For the wake-up
+     * proximity sensor set the flag SENSOR_FLAG_WAKE_UP.
+     * The value corresponds to the distance to the nearest object in
+     * centimeters.
+     */
+    SENSOR_TYPE_PROXIMITY                       = 8,
+
+    /*
+     * SENSOR_TYPE_GRAVITY
+     * reporting-mode: continuous
+     *
+     * A gravity output indicates the direction of and magnitude of gravity in
+     * the devices's coordinates.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_GRAVITY                         = 9,
+
+    /*
+     * SENSOR_TYPE_LINEAR_ACCELERATION
+     * reporting-mode: continuous
+     *
+     * Indicates the linear acceleration of the device in device coordinates,
+     * not including gravity.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_LINEAR_ACCELERATION             = 10,
+
+    /*
+     * SENSOR_TYPE_ROTATION_VECTOR
+     * reporting-mode: continuous
+     *
+     * The rotation vector symbolizes the orientation of the device relative to
+     * the East-North-Up coordinates frame.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_ROTATION_VECTOR                 = 11,
+
+    /*
+     * SENSOR_TYPE_RELATIVE_HUMIDITY
+     * reporting-mode: on-change
+     *
+     * A relative humidity sensor measures relative ambient air humidity and
+     * returns a value in percent.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    SENSOR_TYPE_RELATIVE_HUMIDITY               = 12,
+
+    /*
+     * SENSOR_TYPE_AMBIENT_TEMPERATURE
+     * reporting-mode: on-change
+     *
+     * The ambient (room) temperature in degree Celsius.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    SENSOR_TYPE_AMBIENT_TEMPERATURE             = 13,
+
+    /*
+     * SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
+     * reporting-mode: continuous
+     *
+     * Similar to SENSOR_TYPE_MAGNETIC_FIELD, but the hard iron calibration is
+     * reported separately instead of being included in the measurement.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED     = 14,
+
+    /*
+     * SENSOR_TYPE_GAME_ROTATION_VECTOR
+     * reporting-mode: continuous
+     *
+     * Similar to SENSOR_TYPE_ROTATION_VECTOR, but not using the geomagnetic
+     * field.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_GAME_ROTATION_VECTOR            = 15,
+
+    /*
+     * SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+     * reporting-mode: continuous
+     *
+     * All values are in radians/second and measure the rate of rotation
+     * around the X, Y and Z axis.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_GYROSCOPE_UNCALIBRATED          = 16,
+
+    /*
+     * SENSOR_TYPE_SIGNIFICANT_MOTION
+     * reporting-mode: one-shot
+     *
+     * A sensor of this type triggers an event each time significant motion
+     * is detected and automatically disables itself.
+     * For Significant Motion sensor to be useful, it must be defined as a
+     * wake-up sensor. (set SENSOR_FLAG_WAKE_UP). Implement the wake-up
+     * significant motion sensor. A non wake-up version is not useful.
+     * The only allowed value to return is 1.0.
+     */
+    SENSOR_TYPE_SIGNIFICANT_MOTION              = 17,
+
+    /*
+     * SENSOR_TYPE_STEP_DETECTOR
+     * reporting-mode: special
+     *
+     * A sensor of this type triggers an event each time a step is taken
+     * by the user. The only allowed value to return is 1.0 and an event
+     * is generated for each step.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    SENSOR_TYPE_STEP_DETECTOR                   = 18,
+
+    /*
+     * SENSOR_TYPE_STEP_COUNTER
+     * reporting-mode: on-change
+     *
+     * A sensor of this type returns the number of steps taken by the user since
+     * the last reboot while activated. The value is returned as a uint64_t and
+     * is reset to zero only on a system / android reboot.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_STEP_COUNTER                    = 19,
+
+    /*
+     * SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
+     * reporting-mode: continuous
+     *
+     *  Similar to SENSOR_TYPE_ROTATION_VECTOR, but using a magnetometer instead
+     *  of using a gyroscope.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR     = 20,
+
+    /*
+     * SENSOR_TYPE_HEART_RATE
+     * reporting-mode: on-change
+     *
+     *  A sensor of this type returns the current heart rate.
+     *  The events contain the current heart rate in beats per minute (BPM) and
+     *  the status of the sensor during the measurement. See "HeartRate" below
+     *  for more details.
+     *
+     *  Because this sensor is on-change, events must be generated when and only
+     *  when heart_rate.bpm or heart_rate.status have changed since the last
+     *  event. In particular, upon the first activation, unless the device is
+     *  known to not be on the body, the status field of the first event must be
+     *  set to SENSOR_STATUS_UNRELIABLE. The event should be generated no faster
+     *  than every period_ns passed to setDelay() or to batch().
+     *  See the definition of the on-change reporting mode for more information.
+     *
+     *  SensorInfo.requiredPermission must be set to
+     *  SENSOR_PERMISSION_BODY_SENSORS.
+     *
+     *  Both wake-up and non wake-up versions are useful.
+     */
+    SENSOR_TYPE_HEART_RATE                      = 21,
+
+    /*
+     * SENSOR_TYPE_WAKE_UP_TILT_DETECTOR
+     * reporting-mode: special (setDelay has no impact)
+     *
+     * A sensor of this type generates an event each time a tilt event is
+     * detected. A tilt event should be generated if the direction of the
+     * 2-seconds window average gravity changed by at least 35 degrees since the
+     * activation or the last trigger of the sensor.
+     *
+     *  reference_estimated_gravity = average of accelerometer measurements over
+     *  the first 1 second after activation or the estimated gravity at the last
+     *  trigger.
+     *
+     *  current_estimated_gravity = average of accelerometer measurements over
+     *  the last 2 seconds.
+     *
+     *  trigger when
+     *     angle(reference_estimated_gravity, current_estimated_gravity)
+     *       > 35 degrees
+     *
+     * Large accelerations without a change in phone orientation should not
+     * trigger a tilt event.
+     * For example, a sharp turn or strong acceleration while driving a car
+     * should not trigger a tilt event, even though the angle of the average
+     * acceleration might vary by more than 35 degrees.
+     *
+     * Typically, this sensor is implemented with the help of only an
+     * accelerometer. Other sensors can be used as well if they do not increase
+     * the power consumption significantly. This is a low power sensor that
+     * should allow the AP to go into suspend mode. Do not emulate this sensor
+     * in the HAL.
+     * Like other wake up sensors, the driver is expected to a hold a wake_lock
+     * with a timeout of 200 ms while reporting this event. The only allowed
+     * return value is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    SENSOR_TYPE_TILT_DETECTOR                   = 22,
+
+    /*
+     * SENSOR_TYPE_WAKE_GESTURE
+     * reporting-mode: one-shot
+     *
+     * A sensor enabling waking up the device based on a device specific motion.
+     *
+     * When this sensor triggers, the device behaves as if the power button was
+     * pressed, turning the screen on. This behavior (turning on the screen when
+     * this sensor triggers) might be deactivated by the user in the device
+     * settings. Changes in settings do not impact the behavior of the sensor:
+     * only whether the framework turns the screen on when it triggers.
+     *
+     * The actual gesture to be detected is not specified, and can be chosen by
+     * the manufacturer of the device.
+     * This sensor must be low power, as it is likely to be activated 24/7.
+     * The only allowed value to return is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    SENSOR_TYPE_WAKE_GESTURE                    = 23,
+
+    /*
+     * SENSOR_TYPE_GLANCE_GESTURE
+     * reporting-mode: one-shot
+     *
+     * A sensor enabling briefly turning the screen on to enable the user to
+     * glance content on screen based on a specific motion.  The device should
+     * turn the screen off after a few moments.
+     *
+     * When this sensor triggers, the device turns the screen on momentarily
+     * to allow the user to glance notifications or other content while the
+     * device remains locked in a non-interactive state (dozing). This behavior
+     * (briefly turning on the screen when this sensor triggers) might be
+     * deactivated by the user in the device settings.
+     * Changes in settings do not impact the behavior of the sensor: only
+     * whether the framework briefly turns the screen on when it triggers.
+     *
+     * The actual gesture to be detected is not specified, and can be chosen by
+     * the manufacturer of the device.
+     * This sensor must be low power, as it is likely to be activated 24/7.
+     * The only allowed value to return is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    SENSOR_TYPE_GLANCE_GESTURE                  = 24,
+
+    /**
+     * SENSOR_TYPE_PICK_UP_GESTURE
+     * reporting-mode: one-shot
+     *
+     * A sensor of this type triggers when the device is picked up regardless of
+     * wherever is was before (desk, pocket, bag). The only allowed return value
+     * is 1.0. This sensor de-activates itself immediately after it triggers.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    SENSOR_TYPE_PICK_UP_GESTURE                 = 25,
+
+    /*
+     * SENSOR_TYPE_WRIST_TILT_GESTURE
+     * trigger-mode: special
+     * wake-up sensor: yes
+     *
+     * A sensor of this type triggers an event each time a tilt of the
+     * wrist-worn device is detected.
+     *
+     * This sensor must be low power, as it is likely to be activated 24/7.
+     * The only allowed value to return is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    SENSOR_TYPE_WRIST_TILT_GESTURE              = 26,
+
+    /*
+     * SENSOR_TYPE_DEVICE_ORIENTATION
+     * reporting-mode: on-change
+     *
+     * The current orientation of the device. The value should be reported in
+     * the "scalar" element of the EventPayload in Event. The
+     * only values that can be reported are (please refer to Android Sensor
+     * Coordinate System to understand the X and Y axis direction with respect
+     * to default orientation):
+     *  - 0: device is in default orientation (Y axis is vertical and points up)
+     *  - 1: device is rotated 90 degrees counter-clockwise from default
+     *       orientation (X axis is vertical and points up)
+     *  - 2: device is rotated 180 degrees from default orientation (Y axis is
+     *       vertical and points down)
+     *  - 3: device is rotated 90 degrees clockwise from default orientation
+     *       (X axis is vertical and points down)
+     *
+     * Moving the device to an orientation where the Z axis is vertical (either
+     * up or down) should not cause a new event to be reported.
+     *
+     * To improve the user experience of this sensor, it is recommended to
+     * implement some physical (i.e., rotation angle) and temporal (i.e., delay)
+     * hysteresis.
+     * In other words, minor or transient rotations should not cause a new event
+     * to be reported.
+     *
+     * This sensor should only be implemented with the help of an accelerometer.
+     * This is a low power sensor that should reduce the number of interrupts of
+     * the AP. Do not emulate this sensor in the HAL.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    SENSOR_TYPE_DEVICE_ORIENTATION              = 27,
+
+    /*
+     * SENSOR_TYPE_POSE_6DOF
+     * trigger-mode: continuous
+     *
+     * A sensor of this type returns the pose of the device.
+     * Pose of the device is defined as the orientation of the device from a
+     * Earth Centered Earth Fixed frame and the translation from an arbitrary
+     * point at subscription.
+     *
+     * This sensor can be high power. It can use any and all of the following
+     *           . Accelerometer
+     *           . Gyroscope
+     *           . Camera
+     *           . Depth Camera
+     *
+     */
+    SENSOR_TYPE_POSE_6DOF                       = 28,
+
+    /*
+     * SENSOR_TYPE_STATIONARY_DETECT
+     * trigger mode: one shot
+     *
+     * A sensor of this type returns an event if the device is still/stationary
+     * for a while. The period of time to monitor for statinarity should be
+     * greater than 5 seconds, and less than 10 seconds.
+     *
+     * Stationarity here refers to absolute stationarity. eg: device on desk.
+     *
+     * The only allowed value to return is 1.0.
+     */
+    SENSOR_TYPE_STATIONARY_DETECT               = 29,
+
+    /*
+     * SENSOR_TYPE_MOTION_DETECT
+     * trigger mode: one shot
+     *
+     * A sensor of this type returns an event if the device is not still for
+     * a while. The period of time to monitor for statinarity should be greater
+     * than 5 seconds, and less than 10 seconds.
+     *
+     * Motion here refers to any mechanism in which the device is causes to be
+     * moved in its inertial frame. eg: Pickin up the device and walking with it
+     * to a nearby room may trigger motion wherewas keeping the device on a
+     * table on a smooth train moving at constant velocity may not trigger
+     * motion.
+     *
+     * The only allowed value to return is 1.0.
+     */
+    SENSOR_TYPE_MOTION_DETECT                   = 30,
+
+    /*
+     * SENSOR_TYPE_HEART_BEAT
+     * trigger mode: continuous
+     *
+     * A sensor of this type returns an event everytime a hear beat peak is
+     * detected.
+     *
+     * Peak here ideally corresponds to the positive peak in the QRS complex of
+     * and ECG signal.
+     *
+     * The sensor is not expected to be optimized for latency. As a guide, a
+     * latency of up to 10 seconds is acceptable. However the timestamp attached
+     * to the event should be accurate and should correspond to the time the
+     * peak occured.
+     *
+     * The sensor event contains a parameter for the confidence in the detection
+     * of the peak where 0.0 represent no information at all, and 1.0 represents
+     * certainty.
+     */
+    SENSOR_TYPE_HEART_BEAT                      = 31,
+
+    /**
+     * SENSOR_TYPE_DYNAMIC_SENSOR_META
+     * trigger-mode: special
+     *
+     * A sensor event of this type is received when a dynamic sensor is added to
+     * or removed from the system. At most one sensor of this type can be
+     * present in one sensor HAL implementation and presence of a sensor of this
+     * type in sensor HAL implementation indicates that this sensor HAL supports
+     * dynamic sensor feature. Operations, such as batch, activate and setDelay,
+     * to this special purpose sensor should be treated as no-op and return
+     * successful; flush() also has to generate flush complete event as if this
+     * is a sensor that does not support batching.
+     *
+     * A dynamic sensor connection indicates connection of a physical device or
+     * instantiation of a virtual sensor backed by algorithm; and a dynamic
+     * sensor disconnection indicates the the opposite. A sensor event of
+     * SENSOR_TYPE_DYNAMIC_SENSOR_META type should be delivered regardless of
+     * the activation status of the sensor in the event of dynamic sensor
+     * connection and disconnection. In the sensor event, besides the common
+     * data entries, "dynamic_sensor_meta", which includes fields for connection
+     * status, handle of the sensor involved, pointer to sensor_t structure and
+     * a uuid field, should be populated.
+     *
+     * At a dynamic sensor connection event, fields of sensor_t structure
+     * referenced by a pointer in dynamic_sensor_meta should be filled as if it
+     * was regular sensors. Sensor HAL is responsible for recovery of memory if
+     * the corresponding data is dynamicially allocated. However, the the
+     * pointer must be valid until the first activate call to the sensor
+     * reported in this connection event. At a dynamic sensor disconnection,
+     * the sensor_t pointer should be NULL.
+     *
+     * The sensor handle assigned to dynamic sensors should never be the same as
+     * that of any regular static sensors, and should be unique until next boot.
+     * In another word, if a handle h is used for a dynamic sensor A, that same
+     * number cannot be used for the same dynamic sensor A or another dynamic
+     * sensor B even after disconnection of A until reboot.
+     *
+     * The UUID field will be used for identifying the sensor in addition to
+     * name, vendor and version and type. For physical sensors of the same
+     * model, all sensors will have the same values in sensor_t, but the UUID
+     * should be unique and persistent for each individual unit. An all zero
+     * UUID indicates it is not possible to differentiate individual sensor
+     * unit.
+     *
+     */
+    SENSOR_TYPE_DYNAMIC_SENSOR_META             = 32,
+
+    /**
+     * SENSOR_TYPE_ADDITIONAL_INFO
+     * reporting-mode: N/A
+     *
+     * This sensor type is for delivering additional sensor information aside
+     * from sensor event data.
+     * Additional information may include sensor front-end group delay, internal
+     * calibration parameters, noise level metrics, device internal temperature,
+     * etc.
+     *
+     * This type will never bind to a sensor. In other words, no sensor in the
+     * sensor list should be of the type SENSOR_TYPE_ADDITIONAL_INFO. If a
+     * sensor HAL supports sensor additional information feature, it reports
+     * sensor_event_t with "sensor" field set to handle of the reporting sensor
+     * and "type" field set to SENSOR_TYPE_ADDITIONAL_INFO. Delivery of
+     * additional information events is triggered under two conditions: an
+     * enable activate() call or a flush() call to the corresponding sensor.
+     *
+     * A single additional information report consists of multiple frames.
+     * Sequences of these frames are ordered using timestamps, which means the
+     * timestamps of sequential frames have to be at least 1 nanosecond apart
+     * from each other. Each frame is a sensor_event_t delivered through the HAL
+     * interface, with related data stored in the "additional_info" field, which
+     * is of type additional_info_event_t.
+     * The "type" field of additional_info_event_t denotes the nature of the
+     * payload data (see additional_info_type_t).
+     * The "serial" field is used to keep the sequence of payload data that
+     * spans multiple frames. The first frame of the entire report is always of
+     * type AINFO_BEGIN, and the last frame is always AINFO_END.
+     *
+     * All additional information frames have to be delivered after flush
+     * complete event if flush() was triggering the report.
+     */
+    SENSOR_TYPE_ADDITIONAL_INFO                 = 33,
+
+    /*
+     * Base for device manufacturers private sensor types.
+     * These sensor types can't be exposed in the SDK.
+     */
+    SENSOR_TYPE_DEVICE_PRIVATE_BASE             = 0x10000
+};
+
+@export(name="")
+enum SensorFlagBits : uint64_t {
+    /*
+     * Whether this sensor wakes up the AP from suspend mode when data is
+     * available.  Whenever sensor events are delivered from a wake_up sensor,
+     * the driver needs to hold a wake_lock till the events are read by the
+     * SensorService i.e till ISensors::poll() is called the next time.
+     * Once poll is called again it means events have been read by the
+     * SensorService, the driver can safely release the wake_lock. SensorService
+     * will continue to hold a wake_lock till the app actually reads the events.
+     */
+    SENSOR_FLAG_WAKE_UP                     = 1,
+
+    /*
+     * Reporting modes for various sensors. Each sensor will have exactly one of
+     * these modes set.
+     * The least significant 2nd, 3rd and 4th bits are used to represent four
+     * possible reporting modes.
+     */
+    SENSOR_FLAG_CONTINUOUS_MODE             = 0,
+    SENSOR_FLAG_ON_CHANGE_MODE              = 2,
+    SENSOR_FLAG_ONE_SHOT_MODE               = 4,
+    SENSOR_FLAG_SPECIAL_REPORTING_MODE      = 6,
+
+    /*
+     * Set this flag if the sensor supports data_injection mode and allows data
+     * to be injected from the SensorService. When in data_injection ONLY
+     * sensors with this flag set are injected sensor data and only sensors with
+     * this flag set are activated. Eg: Accelerometer and Step Counter sensors
+     * can be set with this flag and SensorService will inject accelerometer
+     * data and read the corresponding step counts.
+     */
+    SENSOR_FLAG_SUPPORTS_DATA_INJECTION     = 0x10,
+
+    /*
+     * Set this flag if the sensor is a dynamically connected sensor. See
+     * DynamicSensorInfo and DYNAMIC_SENSOR_META for details.
+     */
+    SENSOR_FLAG_DYNAMIC_SENSOR              = 0x20,
+
+    /*
+     * Set this flag if sensor additional information is supported.
+     * See ADDITIONAL_INFO and AdditionalInfo for details.
+     */
+    SENSOR_FLAG_ADDITIONAL_INFO             = 0x40,
+};
+
+struct SensorInfo {
+    /* handle that identifies this sensors. This handle is used to reference
+     * this sensor throughout the HAL API.
+     */
+    int32_t sensorHandle;
+
+    /* Name of this sensor.
+     * All sensors of the same "type" must have a different "name".
+     */
+    string name;
+
+    /* vendor of the hardware part */
+    string vendor;
+
+    /* version of the hardware part + driver. The value of this field
+     * must increase when the driver is updated in a way that changes the
+     * output of this sensor. This is important for fused sensors when the
+     * fusion algorithm is updated.
+     */
+    int32_t version;
+
+    /* this sensor's type. */
+    SensorType type;
+
+    /* type of this sensor as a string. Set to corresponding
+     * SENSOR_STRING_TYPE_*.
+     * When defining an OEM specific sensor or sensor manufacturer specific
+     * sensor, use your reserve domain name as a prefix.
+     * ex: com.google.glass.onheaddetector
+     * For sensors of known type, the android framework might overwrite this
+     * string automatically.
+     */
+    string typeAsString;
+
+    /* maximum range of this sensor's value in SI units */
+    float maxRange;
+
+    /* smallest difference between two values reported by this sensor */
+    float resolution;
+
+    /* rough estimate of this sensor's power consumption in mA */
+    float power;
+
+    /* this value depends on the reporting mode:
+     *
+     *   continuous: minimum sample period allowed in microseconds
+     *   on-change : 0
+     *   one-shot  :-1
+     *   special   : 0, unless otherwise noted
+     */
+    int32_t minDelay;
+
+    /* number of events reserved for this sensor in the batch mode FIFO.
+     * If there is a dedicated FIFO for this sensor, then this is the
+     * size of this FIFO. If the FIFO is shared with other sensors,
+     * this is the size reserved for that sensor and it can be zero.
+     */
+    uint32_t fifoReservedEventCount;
+
+    /* maximum number of events of this sensor that could be batched.
+     * This is especially relevant when the FIFO is shared between
+     * several sensors; this value is then set to the size of that FIFO.
+     */
+    uint32_t fifoMaxEventCount;
+
+    /* permission required to see this sensor, register to it and receive data.
+     * Set to "" if no permission is required. Some sensor types like the
+     * heart rate monitor have a mandatory require_permission.
+     * For sensors that always require a specific permission, like the heart
+     * rate monitor, the android framework might overwrite this string
+     * automatically.
+     */
+    string requiredPermission;
+
+    /* This value is defined only for continuous mode and on-change sensors.
+     * It is the delay between two sensor events corresponding to the lowest
+     * frequency that this sensor supports. When lower frequencies are requested
+     * through batch()/setDelay() the events will be generated at this frequency
+     * instead.
+     * It can be used by the framework or applications to estimate when the
+     * batch FIFO may be full.
+     *
+     * NOTE: periodNs is in nanoseconds where as maxDelay/minDelay are in
+     *       microseconds.
+     *
+     *       continuous, on-change: maximum sampling period allowed in
+     *                              microseconds.
+     *
+     *          one-shot, special : 0
+     */
+    int32_t maxDelay;
+
+    /* Bitmask of SensorFlagBits */
+    uint64_t flags;
+};
+
+@export(name="")
+enum SensorStatus : int8_t {
+    SENSOR_STATUS_NO_CONTACT      = -1,
+    SENSOR_STATUS_UNRELIABLE      = 0,
+    SENSOR_STATUS_ACCURACY_LOW    = 1,
+    SENSOR_STATUS_ACCURACY_MEDIUM = 2,
+    SENSOR_STATUS_ACCURACY_HIGH   = 3,
+};
+
+struct Vec3 {
+    float x;
+    float y;
+    float z;
+    SensorStatus status;
+};
+
+struct Vec4 {
+    float x;
+    float y;
+    float z;
+    float w;
+};
+
+struct Uncal {
+    float x;
+    float y;
+    float z;
+    float x_bias;
+    float y_bias;
+    float z_bias;
+};
+
+struct HeartRate {
+    /* Heart rate in beats per minute.
+     * Set to 0 when status is SENSOR_STATUS_UNRELIABLE or ..._NO_CONTACT
+     */
+    float bpm;
+
+    /* Status of the sensor for this reading. Set to one SENSOR_STATUS_...
+     * Note that this value should only be set for sensors that explicitly
+     * define the meaning of this field. This field is not piped through the
+     * framework for other sensors.
+     */
+    SensorStatus status;
+};
+
+@export(name="")
+enum MetaDataEventType : uint32_t {
+    META_DATA_FLUSH_COMPLETE = 1,
+};
+
+struct MetaData {
+    MetaDataEventType what;
+};
+
+struct DynamicSensorInfo {
+    bool connected;
+    int32_t sensorHandle;
+
+    /* UUID of a dynamic sensor (using RFC 4122 byte order)
+     * For UUID 12345678-90AB-CDEF-1122-334455667788 the uuid field should be
+     * initialized as:
+     *   {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x11, ...}
+     */
+    uint8_t[16] uuid;
+};
+
+@export(name="additional_info_type_t")
+enum AdditionalInfoType : uint32_t {
+    /* Marks the beginning of additional information frames */
+    AINFO_BEGIN                       = 0,
+
+    /* Marks the end of additional information frames */
+    AINFO_END                         = 1,
+
+    /* Estimation of the delay that is not tracked by sensor timestamps. This
+     * includes delay introduced by sensor front-end filtering, data transport,
+     * etc.
+     * float[2]: delay in seconds, standard deviation of estimated value
+     */
+    AINFO_UNTRACKED_DELAY             = 0x10000,
+
+    /* float: Celsius temperature */
+    AINFO_INTERNAL_TEMPERATURE,
+
+    /* First three rows of a homogeneous matrix, which represents calibration to
+     * a three-element vector raw sensor reading.
+     * float[12]: 3x4 matrix in row major order
+     */
+    AINFO_VEC3_CALIBRATION,
+
+    /* Location and orientation of sensor element in the device frame: origin is
+     * the geometric center of the mobile device screen surface; the axis
+     * definition corresponds to Android sensor definitions.
+     * float[12]: 3x4 matrix in row major order
+     */
+    AINFO_SENSOR_PLACEMENT,
+
+    /* float[2]: raw sample period in seconds,
+     *           standard deviation of sampling period
+     */
+    AINFO_SAMPLING,
+
+    /* Sampling channel modeling information
+     * int32_t: noise type
+     * float[n]: parameters
+     */
+    AINFO_CHANNEL_NOISE               = 0x20000,
+
+    /* float[3]: sample period, standard deviation of sample period,
+     * quantization unit
+     */
+    AINFO_CHANNEL_SAMPLER,
+
+    /* Represents a filter:
+     *   \sum_j a_j y[n-j] == \sum_i b_i x[n-i]
+     *
+     * int32_t[3]: number of feedforward coeffients M,
+     *             number of feedback coefficients N (for FIR filter, N = 1).
+     *             bit mask that represents which element the filter is applied
+     *             to. (bit 0==1 means this filter applies to vector element 0).
+     * float[M+N]: filter coefficients (b0, b1, ..., b_{M-1}), then
+     *             (a0, a1, ..., a_{N-1}), a0 is always 1.
+     *
+     * Multiple frames may be needed for higher number of taps.
+     */
+    AINFO_CHANNEL_FILTER,
+
+    /* int32_t[2]: size in (row, column) ... 1st frame
+     * float[n]: matrix element values in row major order.
+     */
+    AINFO_CHANNEL_LINEAR_TRANSFORM,
+
+    /* int32_t[2]: extrapolate method, interpolate method
+     * float[n]: mapping key points in paris, (in, out)...
+     *           (may be used to model saturation).
+     */
+    AINFO_CHANNEL_NONLINEAR_MAP,
+
+    /* int32_t: resample method (0-th order, 1st order...)
+     * float[1]: resample ratio (upsampling if < 1.0, downsampling if > 1.0).
+     */
+    AINFO_CHANNEL_RESAMPLER,
+
+    /* Custom information */
+    AINFO_CUSTOM_START                = 0x10000000,
+
+    /* Debugging */
+    AINFO_DEBUGGING_START             = 0x40000000,
+};
+
+struct AdditionalInfo {
+    /* type of payload data, see AdditionalInfoType */
+    AdditionalInfoType type;
+
+    /* sequence number of this frame for this type */
+    int32_t serial;
+
+    union Payload {
+        /* for each frame, a single data type, either int32_t or float,
+         * should be used.
+         */
+        int32_t[14] data_int32;
+        float[14] data_float;
+    } u;
+};
+
+/* acceleration values are in meter per second per second (m/s^2)
+ * magnetic vector values are in micro-Tesla (uT)
+ * orientation values are in degrees
+ * gyroscope values are in rad/s
+ * temperature is in degrees centigrade (Celsius)
+ * distance in centimeters
+ * light in SI lux units
+ * pressure in hectopascal (hPa)
+ * relative humidity in percent
+ */
+union EventPayload {
+    /* SENSOR_TYPE_ACCELEROMETER, SENSOR_TYPE_GEOMAGNETIC_FIELD,
+     * SENSOR_TYPE_ORIENTATION, SENSOR_TYPE_GYROSCOPE, SENSOR_TYPE_GRAVITY,
+     * SENSOR_TYPE_LINEAR_ACCELERATION
+     */
+    Vec3 vec3;
+
+    /* SENSOR_TYPE_ROTATION_VECTOR, SENSOR_TYPE_GAME_ROTATION_VECTOR,
+     * SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
+     */
+    Vec4 vec4;
+
+    /* SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+     * SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+     */
+    Uncal uncal;
+
+    /* SENSOR_TYPE_META_DATA */
+    MetaData meta;
+
+    /* SENSOR_TYPE_DEVICE_ORIENTATION, SENSOR_TYPE_LIGHT, SENSOR_TYPE_PRESSURE,
+     * SENSOR_TYPE_TEMPERATURE, SENSOR_TYPE_PROXIMITY,
+     * SENSOR_TYPE_RELATIVE_HUMIDITY, SENSOR_TYPE_AMBIENT_TEMPERATURE,
+     * SENSOR_TYPE_SIGNIFICANT_MOTION, SENSOR_TYPE_STEP_DETECTOR,
+     * SENSOR_TYPE_TILT_DETECTOR, SENSOR_TYPE_WAKE_GESTURE,
+     * SENSOR_TYPE_GLANCE_GESTURE, SENSOR_TYPE_PICK_UP_GESTURE,
+     * SENSOR_TYPE_WRIST_TILT_GESTURE, SENSOR_TYPE_STATIONARY_DETECT,
+     * SENSOR_TYPE_MOTION_DETECT, SENSOR_TYPE_HEART_BEAT
+     */
+    float scalar;
+
+    /* SENSOR_TYPE_STEP_COUNTER */
+    uint64_t stepCount;
+
+    /* SENSOR_TYPE_HEART_RATE */
+    HeartRate heartRate;
+
+    /* SENSOR_TYPE_POSE_6DOF */
+    float[15] pose6DOF;
+
+    /* SENSOR_TYPE_DYNAMIC_SENSOR_META */
+    DynamicSensorInfo dynamic;
+
+    /* SENSOR_TYPE_ADDITIONAL_INFO */
+    AdditionalInfo additional;
+
+    /* undefined/custom sensor type, >= SENSOR_TYPE_DEVICE_PRIVATE_BASE */
+    float[16] data;
+};
+
+struct Event {
+    /* Time measured in nanoseconds, in "elapsedRealtimeNano()'s" timebase. */
+    int64_t timestamp;
+
+    /* sensor identifier */
+    int32_t sensorHandle;
+
+    SensorType sensorType;
+
+    /* Union discriminated on sensorType */
+    EventPayload u;
+};