/*
 * 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,
    PERMISSION_DENIED                   = -1,
    NO_MEMORY                           = -12,
    BAD_VALUE                           = -22,
    INVALID_OPERATION                   = -38,
};

/**
 * Sensor HAL modes used in setOperationMode method
 */
@export(name="", value_prefix="SENSOR_HAL_", value_suffix="_MODE")
enum OperationMode : int32_t {
    NORMAL                          = 0,
    DATA_INJECTION                  = 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 SensorType::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".
 *  - string type of sensors defined in this file is overridden by Android to
 *    values defined in Android API with "android.sensor." prefix.
 *    Example: for an accelerometer,
 *      type = SensorType::Acclerometer
 *      typeAsString = "" (will be replace by "android.sensor.accelerometer" by
 *                         Android frameowrk)
 *  - string type 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.
 *
 * 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
 *      typeAsString = "com.google.glass.onheaddetector"
 *  - In L android release, if android decides to define
 *    SensorType::ON_HEAD_DETECTOR and STRING_SensorType::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 (SensorType::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 must 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
 * SensorType::PROXIMITY and SensorType::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 SensorType::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="", value_prefix="SENSOR_TYPE_")
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.
     */
    META_DATA                       = 0,

    /**
     * ACCELEROMETER
     * reporting-mode: continuous
     *
     * All values are in SI units (m/s^2) and measure the acceleration of the
     * device minus the acceleration due to gravity.
     *
     * Implement the non-wake-up version of this sensor and implement the
     * wake-up version if the system possesses a wake up fifo.
     */
    ACCELEROMETER                   = 1,

    /**
     * MAGNETIC_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.
     */
    MAGNETIC_FIELD                  = 2,

    /**
     * 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.
     */
    ORIENTATION                     = 3,

    /**
     * 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.
     */
    GYROSCOPE                       = 4,

    /**
     * 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.
     */
    LIGHT                           = 5,

    /**
     * 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.
     */
    PRESSURE                        = 6,

    /** TEMPERATURE is deprecated in the HAL */
    TEMPERATURE                     = 7,

    /**
     * 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.
     */
    PROXIMITY                       = 8,

    /**
     * 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.
     */
    GRAVITY                         = 9,

    /**
     * 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.
     */
    LINEAR_ACCELERATION             = 10,

    /**
     * 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.
     */
    ROTATION_VECTOR                 = 11,

    /**
     * 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.
     */
    RELATIVE_HUMIDITY               = 12,

    /**
     * AMBIENT_TEMPERATURE
     * reporting-mode: on-change
     *
     * The ambient (room) temperature in degree Celsius.
     *
     * Both wake-up and non wake-up versions are useful.
     */
    AMBIENT_TEMPERATURE             = 13,

    /**
     * MAGNETIC_FIELD_UNCALIBRATED
     * reporting-mode: continuous
     *
     * Similar to 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.
     */
    MAGNETIC_FIELD_UNCALIBRATED     = 14,

    /**
     * GAME_ROTATION_VECTOR
     * reporting-mode: continuous
     *
     * Similar to 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.
     */
    GAME_ROTATION_VECTOR            = 15,

    /**
     * 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.
     */
    GYROSCOPE_UNCALIBRATED          = 16,

    /**
     * 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.
     */
    SIGNIFICANT_MOTION              = 17,

    /**
     * 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.
     */
    STEP_DETECTOR                   = 18,

    /**
     * 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.
     */
    STEP_COUNTER                    = 19,

    /**
     * GEOMAGNETIC_ROTATION_VECTOR
     * reporting-mode: continuous
     *
     *  Similar to 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.
     */
    GEOMAGNETIC_ROTATION_VECTOR     = 20,

    /**
     * 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 SensorStatus::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.
     */
    HEART_RATE                      = 21,

    /**
     * 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 must 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 must not
     * trigger a tilt event.
     * For example, a sharp turn or strong acceleration while driving a car
     * must 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
     * must 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.
     */
    TILT_DETECTOR                   = 22,

    /**
     * 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.
     */
    WAKE_GESTURE                    = 23,

    /**
     * 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 must
     * 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.
     */
    GLANCE_GESTURE                  = 24,

    /**
     * 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.
     */
    PICK_UP_GESTURE                 = 25,

    /**
     * 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.
     */
    WRIST_TILT_GESTURE              = 26,

    /**
     * DEVICE_ORIENTATION
     * reporting-mode: on-change
     *
     * The current orientation of the device. The value is 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) must 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 must not cause
     * a new event to be reported.
     *
     * This is a low power sensor that intended to reduce interrupts of
     * application processor and thus allow it to go sleep. Use hardware
     * implementation based on low power consumption sensors, such as
     * accelerometer. Device must not emulate this sensor in the HAL.
     *
     * Both wake-up and non wake-up versions are useful.
     */
    DEVICE_ORIENTATION              = 27,

    /**
     * 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
     *
     */
    POSE_6DOF                       = 28,

    /**
     * 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 stationarity must be
     * greater than 5 seconds. The latency must be less than 10 seconds.
     *
     * Stationarity here refers to absolute stationarity. eg: device on desk.
     *
     * The only allowed value to return is 1.0.
     */
    STATIONARY_DETECT               = 29,

    /**
     * MOTION_DETECT
     * trigger mode: one shot
     *
     * A sensor of this type returns an event if the device is not still for
     * for a while. The period of time to monitor for stationarity must be
     * greater than 5 seconds. The latency must be 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.
     */
    MOTION_DETECT                   = 30,

    /**
     * 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 must be accuratly 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.
     */
    HEART_BEAT                      = 31,

    /**
     * DYNAMIC_SENSOR_META
     * trigger-mode: special
     * wake-up sensor: yes
     *
     * A sensor event of this type is received when a dynamic sensor is added to
     * or removed from the system. At most one sensor of this type can be
     * present in one sensor HAL implementation and presence of a sensor of this
     * type in sensor HAL implementation indicates that this sensor HAL supports
     * dynamic sensor feature. Operations, such as batch, activate and setDelay,
     * to this special purpose sensor must 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
     * 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, must be populated.
     *
     * At a dynamic sensor connection event, fields of sensor_t structure
     * referenced by a pointer in dynamic_sensor_meta must 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 must be NULL.
     *
     * The sensor handle assigned to dynamic sensors must never be the same as
     * that of any regular static sensors, and must 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
     * must be unique and persistent for each individual unit. An all zero
     * UUID indicates it is not possible to differentiate individual sensor
     * unit.
     *
     */
    DYNAMIC_SENSOR_META             = 32,

    /**
     * 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 can have 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 ADDITIONAL_INFO. Delivery of
     * additional information events is triggered under two conditions: an
     * enable activate() call or a flush() call to the corresponding sensor.
     * Besides, time varying parameters can update infrequently without being
     * triggered. Device is responsible to control update rate. The recommend
     * update rate is less than 1/1000 of sensor event rate or less than once
     * per minute in average.
     *
     * 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.
     *
     * If flush() was triggering the report, all additional information frames
     * must be delivered after flush complete event.
     */
    ADDITIONAL_INFO                 = 33,

    /**
     * LOW_LATENCY_OFFBODY_DETECT
     * trigger-mode: on-change
     * wake-up sensor: yes
     *
     * A sensor of this type is defined for devices that are supposed to be worn
     * by the user in the normal use case (such as a watch, wristband, etc) and
     * is not yet defined for other device.
     *
     * A sensor of this type triggers an event each time the wearable device
     * is removed from the body and each time it's put back onto the body.
     * It must be low-latency and be able to detect the on-body to off-body
     * transition within one second (event delivery time included),
     * and 3-second latency to determine the off-body to on-body transition
     * (event delivery time included).
     *
     * There are only two valid event values for the sensor to return :
     *    0.0 for off-body
     *    1.0 for on-body
     *
     */
    LOW_LATENCY_OFFBODY_DETECT      = 34,

    /**
     * ACCELEROMETER_UNCALIBRATED
     * reporting-mode: continuous
     *
     * All values are in SI units (m/s^2) and measure the acceleration of the
     * device minus the acceleration due to gravity.
     *
     * Implement the non-wake-up version of this sensor and implement the
     * wake-up version if the system possesses a wake up fifo.
     */
    ACCELEROMETER_UNCALIBRATED      = 35,

    /**
     * Base for device manufacturers private sensor types.
     * These sensor types can't be exposed in the SDK.
     */
    DEVICE_PRIVATE_BASE             = 0x10000
};

@export(name="", value_prefix="SENSOR_FLAG_")
enum SensorFlagBits : uint32_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.
     */
    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.
     */
    CONTINUOUS_MODE             = 0,
    ON_CHANGE_MODE              = 2,
    ONE_SHOT_MODE               = 4,
    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.
     */
    DATA_INJECTION              = 0x10,

    /**
     * Set this flag if the sensor is a dynamically connected sensor. See
     * DynamicSensorInfo and DYNAMIC_SENSOR_META for details.
     */
    DYNAMIC_SENSOR              = 0x20,

    /**
     * Set this flag if sensor additional information is supported.
     * See ADDITIONAL_INFO and AdditionalInfo for details.
     */
    ADDITIONAL_INFO             = 0x40,

    /**
     * Set this flag if sensor suppor direct channel backed by ashmem.
     * See SharedMemType and registerDirectChannel for more details.
     */
    DIRECT_CHANNEL_ASHMEM       = 0x400,

    /**
     * Set this flag if sensor suppor direct channel backed by gralloc HAL memory.
     * See SharedMemType and registerDirectChannel for more details.
     */
    DIRECT_CHANNEL_GRALLOC      = 0x800,

    /**
     * Flags mask for reporting mode of sensor.
     */
    MASK_REPORTING_MODE         = 0xE,

    /**
     * Flags mask for direct report maximum rate level support.
     * See RateLevel.
     */
    MASK_DIRECT_REPORT          = 0x380,

    /**
     * Flags mask for all direct channel support bits.
     * See SharedMemType.
     */
    MASK_DIRECT_CHANNEL         = 0xC00,
};

@export(name="sensor_flag_shift_t", value_prefix="SENSOR_FLAG_SHIFT_")
enum SensorFlagShift : uint8_t {
    REPORTING_MODE              = 1,
    DATA_INJECTION              = 4,
    DYNAMIC_SENSOR              = 5,
    ADDITIONAL_INFO             = 6,
    DIRECT_REPORT               = 7,
    DIRECT_CHANNEL              = 10,
};

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.
     *
     * When defining an OEM specific sensor or sensor manufacturer specific
     * sensor, use your reserve domain name as a prefix.
     * e.g. com.google.glass.onheaddetector
     *
     * For sensors of known type defined in SensorType (value <
     * SensorType::DEVICE_PRIVATE_BASE), this can be an empty string.
     */
    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 */
    bitfield<SensorFlagBits> flags;
};

@export(name="", value_prefix="SENSOR_STATUS_")
enum SensorStatus : int8_t {
    NO_CONTACT          = -1,
    UNRELIABLE          = 0,
    ACCURACY_LOW        = 1,
    ACCURACY_MEDIUM     = 2,
    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 SensorStatus::UNRELIABLE or
     * SensorStatus::NO_CONTACT
     */
    float bpm;

    /** Status of the heart rate sensor for this reading. */
    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 is
     * 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,

    /**
     * Provides the orientation and location of the sensor element in terms of
     * the Android coordinate system. This data is given as a 3x4 matrix
     * consisting of a 3x3 rotation matrix (R) concatenated with a 3x1 location
     * vector (t). The rotation matrix provides the orientation of the Android
     * device coordinate frame relative to the local coordinate frame of the
     * sensor. Note that assuming the axes conventions of the sensor are the
     * same as Android, this is the inverse of the matrix applied to raw
     * samples read from the sensor to convert them into the Android
     * representation. The location vector represents the translation from the
     * origin of the Android sensor coordinate system to the geometric center
     * of the sensor, specified in millimeters (mm).
     *
     * float[12]: 3x4 matrix in row major order [R; t]
     *
     * Example:
     *     This raw buffer: {0, 1, 0, 0, -1, 0, 0, 10, 0, 0, 1, -2.5}
     *     Corresponds to this 3x4 matrix:
     *         0 1 0    0
     *        -1 0 0   10
     *         0 0 1 -2.5
     *     The sensor is oriented such that:
     *         - the device X axis corresponds to the sensor's local -Y axis
     *         - the device Y axis corresponds to the sensor's local X axis
     *         - the device Z axis and sensor's local Z axis are equivalent
     *     In other words, if viewing the origin of the Android coordinate
     *     system from the positive Z direction, the device coordinate frame is
     *     to be rotated 90 degrees counter-clockwise about the Z axis to align
     *     with the sensor's local coordinate frame. Equivalently, a vector in
     *     the Android coordinate frame may be multiplied with R to rotate it
     *     90 degrees clockwise (270 degrees counter-clockwise), yielding its
     *     representation in the sensor's coordinate frame.
     *     Relative to the origin of the Android coordinate system, the physical
     *     center of the sensor is located 10mm in the positive Y direction, and
     *     2.5mm in the negative Z direction.
     */
    AINFO_SENSOR_PLACEMENT,

    /**
     * float[2]: raw sample period in seconds,
     *           standard deviation of sampling period
     */
    AINFO_SAMPLING,

    // Sampling channel modeling information section

    /**
     * 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 pairs, (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,

    /**
     * Operation environment parameters section
     * Types in the following section is sent down (instead of reported from)
     * device as additional information to aid sensor operation. Data is sent
     * via injectSensorData() function to sensor handle -1 denoting all sensors
     * in device.
     */

    /**
     * Local geomagnetic field information based on device geo location. This
     * type is primarily for for magnetic field calibration and rotation vector
     * sensor fusion.
     * float[3]: strength (uT), declination and inclination angle (rad).
     */
    AINFO_LOCAL_GEOMAGNETIC_FIELD     = 0x30000,

    /**
     * Local gravitational acceleration strength at device geo location.
     * float: gravitational acceleration norm in m/s^2.
     */
    AINFO_LOCAL_GRAVITY,

    /**
     * Device dock state.
     * int32_t: dock state following Android API Intent.EXTRA_DOCK_STATE
     * definition, undefined value is ignored.
     */
    AINFO_DOCK_STATE,

    /**
     * High performance mode hint. Device is able to use up more power and take
     * more resources to improve throughput and latency in high performance mode.
     * One possible use case is virtual reality, when sensor latency need to be
     * carefully controlled.
     * int32_t: 1 or 0, denote if device is in/out of high performance mode,
     *          other values is ignored.
     */
    AINFO_HIGH_PERFORMANCE_MODE,

    /**
     * Magnetic field calibration hint. Device is notified when manually
     * triggered magnetic field calibration procedure is started or stopped. The
     * calibration procedure is assumed timed out after 1 minute from start,
     * even if an explicit stop is not received.
     *
     * int32_t: 1 for start, 0 for stop, other value is ignored.
     */
    AINFO_MAGNETIC_FIELD_CALIBRATION,

    /** 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 {
        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 {
    /**
     * SensorType::ACCELEROMETER, SensorType::MAGNETIC_FIELD,
     * SensorType::ORIENTATION, SensorType::GYROSCOPE, SensorType::GRAVITY,
     * SensorType::LINEAR_ACCELERATION
     */
    Vec3 vec3;

    /**
     * SensorType::GAME_ROTATION_VECTOR
     */
    Vec4 vec4;

    /**
     * SensorType::MAGNETIC_FIELD_UNCALIBRATED,
     * SensorType::GYROSCOPE_UNCALIBRATED
     * SensorType::ACCELEROMETER_UNCALIBRATED
     */
    Uncal uncal;

    /** SensorType::META_DATA */
    MetaData meta;

    /**
     * SensorType::DEVICE_ORIENTATION, SensorType::LIGHT, SensorType::PRESSURE,
     * SensorType::TEMPERATURE, SensorType::PROXIMITY,
     * SensorType::RELATIVE_HUMIDITY, SensorType::AMBIENT_TEMPERATURE,
     * SensorType::SIGNIFICANT_MOTION, SensorType::STEP_DETECTOR,
     * SensorType::TILT_DETECTOR, SensorType::WAKE_GESTURE,
     * SensorType::GLANCE_GESTURE, SensorType::PICK_UP_GESTURE,
     * SensorType::WRIST_TILT_GESTURE, SensorType::STATIONARY_DETECT,
     * SensorType::MOTION_DETECT, SensorType::HEART_BEAT,
     * SensorType::LOW_LATENCY_OFFBODY_DETECT
     */
    float scalar;

    /** SensorType::STEP_COUNTER */
    uint64_t stepCount;

    /** SensorType::HEART_RATE */
    HeartRate heartRate;

    /** SensorType::POSE_6DOF */
    float[15] pose6DOF;

    /** SensorType::DYNAMIC_SENSOR_META */
    DynamicSensorInfo dynamic;

    /** SensorType::ADDITIONAL_INFO */
    AdditionalInfo additional;

    /**
     * The following sensors should use the data field:
     * - Undefined/custom sensor type >= SensorType::DEVICE_PRIVATE_BASE
     * - SensorType::ROTATION_VECTOR, SensorType::GEOMAGNETIC_ROTATION_VECTOR:
     *   - These are Vec4 types with an additional float accuracy field,
     *     where data[4] is the estimated heading accuracy in radians
     *     (-1 if unavailable, and invalid if not in the range (0, 2 * pi]).
     */
    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;
};

/**
 * Direct report rate level definition. Except for SENSOR_DIRECT_RATE_STOP, each
 * rate level covers the range (55%, 220%] * nominal report rate. For example,
 * if config direct report specify a rate level SENSOR_DIRECT_RATE_FAST, it is
 * legal for sensor hardware to report event at a rate greater than 110Hz, and
 * less or equal to 440Hz. Note that rate has to remain steady without variation
 * before new rate level is configured, i.e. if a sensor is configured to
 * SENSOR_DIRECT_RATE_FAST and starts to report event at 256Hz, it cannot
 * change rate to 128Hz after a few seconds of running even if 128Hz is also in
 * the legal range of SENSOR_DIRECT_RATE_FAST. Thus, it is recommended to
 * associate report rate with RateLvel statically for single sensor.
 */
@export(name="direct_rate_level_t", value_prefix="SENSOR_DIRECT_RATE_")
enum RateLevel : int32_t {
    STOP,            // stop
    NORMAL,          // nominal 50Hz
    FAST,            // nominal 200Hz
    VERY_FAST,       // nominal 800Hz
};

/**
 * Direct channel shared memory types. See struct SharedMemInfo.
 */
@export(name="direct_mem_type_t", value_prefix="SENSOR_DIRECT_MEM_TYPE_")
enum SharedMemType : int32_t {
    // handle contains 1 fd (ashmem handle) and 0 int.
    ASHMEM = 1,
    // handle definition matches gralloc HAL.
    GRALLOC
};


/**
 * Direct channel lock-free queue format, this defines how the shared memory is
 * interpreted by both sensor hardware and application.
 *
 * @see SharedMemInfo.
 */
@export(name="direct_format_t", value_prefix="SENSOR_DIRECT_FMT_")
enum SharedMemFormat : int32_t {
    SENSORS_EVENT = 1,  // shared memory is formated as an array of data
                        // elements. See SensorsEventFormatOffset for details.
                        // Upon return of channel registration call, the
                        // shared memory space must be formated to all 0 by HAL.
};

enum SensorsEventFormatOffset : uint16_t {
    // offset   type        name
    //-----------------------------------
    // 0x0000   int32_t     size (always 104)
    // 0x0004   int32_t     sensor report token
    // 0x0008   int32_t     type (see SensorType)
    // 0x000C   uint32_t    atomic counter
    // 0x0010   int64_t     timestamp (see Event)
    // 0x0018   float[16]/  data
    //          int64_t[8]
    // 0x0058   int32_t[4]  reserved (set to zero)
    SIZE_FIELD      = 0x0,
    REPORT_TOKEN    = 0x4,
    SENSOR_TYPE     = 0x8,
    ATOMIC_COUNTER  = 0xC,
    TIMESTAMP       = 0x10,
    DATA            = 0x18,
    RESERVED        = 0x58,
    TOTAL_LENGTH    = 0x68
};

/**
 * Shared memory information for a direct channel
 */
struct SharedMemInfo {
    SharedMemType type;         // shared memory type
    SharedMemFormat format;
    uint32_t size;              // size of the memory region, in bytes
    handle memoryHandle;        // shared memory handle, it is interpreted
                                // depending on type field, see SharedMemType.
};
