/*
* Copyright (C) 2021 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 androidx.health.services.client.data
import android.os.Parcelable
import androidx.health.services.client.data.DataType.TimeType
import androidx.health.services.client.proto.DataProto
import androidx.health.services.client.proto.DataProto.DataType.TimeType.TIME_TYPE_INTERVAL
import androidx.health.services.client.proto.DataProto.DataType.TimeType.TIME_TYPE_SAMPLE
import androidx.health.services.client.proto.DataProto.DataType.TimeType.TIME_TYPE_UNKNOWN
/**
* A data type is a representation of health data managed by Health Services.
*
* A [DataType] specifies the format of the values inside a [DataPoint]. Health Services defines
* data types for instantaneous observations [TimeType.SAMPLE](e.g. heart rate) and data types for
* change between readings [TimeType.INTERVAL](e.g. distance).
*
* Note: the data type defines only the representation and format of the data, and not how it's
* being collected, the sensor being used, or the parameters of the collection.
*/
@Suppress("ParcelCreator")
public class DataType(
/** Returns the name of this [DataType], e.g. `"Steps"`. */
public val name: String,
/** Returns the [TimeType] of this [DataType]. */
public val timeType: TimeType,
/** Returns the expected format for a [Value] of this [DataType]. */
public val format: Int,
) : ProtoParcelable<DataProto.DataType>() {
/** @hide */
public constructor(
proto: DataProto.DataType
) : this(
proto.name,
TimeType.fromProto(proto.timeType)
?: throw IllegalStateException("Invalid TimeType: ${proto.timeType}"),
proto.format
)
/**
* Whether the `DataType` corresponds to a measurement spanning an interval, or a sample at a
* single point in time.
*/
public enum class TimeType {
INTERVAL,
SAMPLE;
/** @hide */
internal fun toProto(): DataProto.DataType.TimeType =
when (this) {
INTERVAL -> TIME_TYPE_INTERVAL
SAMPLE -> TIME_TYPE_SAMPLE
}
internal companion object {
/** @hide */
internal fun fromProto(proto: DataProto.DataType.TimeType): TimeType? =
when (proto) {
TIME_TYPE_INTERVAL -> INTERVAL
TIME_TYPE_SAMPLE -> SAMPLE
TIME_TYPE_UNKNOWN -> null
}
}
}
override fun toString(): String = "DataType(name=$name, timeType=$timeType, format=$format)"
/** @hide */
override val proto: DataProto.DataType by lazy {
DataProto.DataType.newBuilder()
.setName(name)
.setTimeType(timeType.toProto())
.setFormat(format)
.build()
}
public companion object {
@JvmField
public val CREATOR: Parcelable.Creator<DataType> = newCreator {
val proto = DataProto.DataType.parseFrom(it)
DataType(proto)
}
/**
* A measure of the gain in elevation expressed in meters in `double` format. Elevation
* losses are not counted in this metric (so it will only be positive or 0).
*/
@JvmField
public val ELEVATION_GAIN: DataType =
DataType("Elevation Gain", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/** Absolute elevation between each reading expressed in meters in `double` format. */
@JvmField
public val ABSOLUTE_ELEVATION: DataType =
DataType("Absolute Elevation", TimeType.SAMPLE, Value.FORMAT_DOUBLE)
/** A distance delta between each reading expressed in meters in `double` format. */
@JvmField
public val DISTANCE: DataType = DataType("Distance", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/**
* A distance delta traveled over declining ground between each reading expressed in meters
* in `double` format.
*/
@JvmField
public val DECLINE_DISTANCE: DataType =
DataType("Decline Distance", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/**
* A duration delta representing the amount of time the user spent traveling over declining
* ground during the interval, expressed in seconds in `long` format.
*/
@JvmField
public val DECLINE_DURATION: DataType =
DataType("Decline Duration", TimeType.INTERVAL, Value.FORMAT_LONG)
/**
* A distance delta traveled over flat ground between each reading expressed in meters in
* `double` format.
*/
@JvmField
public val FLAT_GROUND_DISTANCE: DataType =
DataType("Flat Ground Distance", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/**
* A duration delta representing the amount of time the user spent traveling over flat
* ground during the interval, expressed in seconds in `long` format.
*/
@JvmField
public val FLAT_GROUND_DURATION: DataType =
DataType("Flat Ground Duration", TimeType.INTERVAL, Value.FORMAT_LONG)
/**
* A distance delta traveled over inclining ground between each reading expressed in meters
* in `double` format.
*/
@JvmField
public val INCLINE_DISTANCE: DataType =
DataType("Incline Distance", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/**
* A duration delta representing the amount of time the user spent traveling over inclining
* ground during the interval, expressed in seconds in `long` format.
*/
@JvmField
public val INCLINE_DURATION: DataType =
DataType("Incline Duration", TimeType.INTERVAL, Value.FORMAT_LONG)
/** Number of floors climbed between each reading in `double` format */
@JvmField
public val FLOORS: DataType = DataType("Floors", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/**
* Current heart rate, in beats per minute in `double` format.
*
* Accuracy for a [DataPoint] of type [DataType.HEART_RATE_BPM] is represented by
* [HrAccuracy].
*/
@JvmField
public val HEART_RATE_BPM: DataType =
DataType("HeartRate", TimeType.SAMPLE, Value.FORMAT_DOUBLE)
/**
* Current latitude, longitude and optionally, altitude in `double[]` format. Latitude at
* index [DataPoints.LOCATION_DATA_POINT_LATITUDE_INDEX], longitude at index
* [DataPoints.LOCATION_DATA_POINT_LONGITUDE_INDEX] and if available, altitude at index
* [DataPoints.LOCATION_DATA_POINT_ALTITUDE_INDEX]
*
* Accuracy for a [DataPoint] of type [DataType.LOCATION] is represented by
* [LocationAccuracy].
*/
@JvmField
public val LOCATION: DataType =
DataType("Location", TimeType.SAMPLE, Value.FORMAT_DOUBLE_ARRAY)
/** Current speed over time. In meters/second in `double` format. */
@JvmField
public val SPEED: DataType = DataType("Speed", TimeType.SAMPLE, Value.FORMAT_DOUBLE)
/** Percentage of oxygen in the blood in `double` format. Valid range `0f` - `100f`. */
@JvmField public val SPO2: DataType = DataType("SpO2", TimeType.SAMPLE, Value.FORMAT_DOUBLE)
/** Rate of oxygen consumption in `double` format. Valid range `0f` - `100f`. */
@JvmField public val VO2: DataType = DataType("VO2", TimeType.SAMPLE, Value.FORMAT_DOUBLE)
/**
* Maximum rate of oxygen consumption measured during incremental exercise in `double`
* format. Valid range `0f` - `100f`.
*/
@JvmField
public val VO2_MAX: DataType = DataType("VO2 Max", TimeType.SAMPLE, Value.FORMAT_DOUBLE)
/** Delta of steps between each reading in `long` format. */
@JvmField
public val STEPS: DataType = DataType("Steps", TimeType.INTERVAL, Value.FORMAT_LONG)
/** Delta of walking steps between each reading in `long` format. */
@JvmField
public val WALKING_STEPS: DataType =
DataType("Walking Steps", TimeType.INTERVAL, Value.FORMAT_LONG)
/** Delta of running steps between each reading in `long` format. */
@JvmField
public val RUNNING_STEPS: DataType =
DataType("Running Steps", TimeType.INTERVAL, Value.FORMAT_LONG)
/** Current step rate in steps/minute in `long` format. */
@JvmField
public val STEPS_PER_MINUTE: DataType =
DataType("Step per minute", TimeType.SAMPLE, Value.FORMAT_LONG)
/** Delta of strokes between each reading of swimming strokes in `long` format. */
@JvmField
public val SWIMMING_STROKES: DataType =
DataType("Swimming Strokes", TimeType.INTERVAL, Value.FORMAT_LONG)
/**
* Delta of total calories (including basal rate and activity) between each reading in
* `double` format.
*/
@JvmField
public val TOTAL_CALORIES: DataType =
DataType("Calories", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/** Current pace. In millisec/km in `double` format. */
@JvmField public val PACE: DataType = DataType("Pace", TimeType.SAMPLE, Value.FORMAT_DOUBLE)
/**
* The duration during which the user was resting during an Exercise in seconds in `long`
* format.
*/
@JvmField
public val RESTING_EXERCISE_DURATION: DataType =
DataType("Resting Exercise Duration", TimeType.INTERVAL, Value.FORMAT_LONG)
/** The duration of the time the Exercise was ACTIVE in seconds in `long` format. */
@JvmField
public val ACTIVE_EXERCISE_DURATION: DataType =
DataType("Active Exercise Duration", TimeType.INTERVAL, Value.FORMAT_LONG)
/** Count of swimming laps ins `long` format. */
@JvmField
public val SWIMMING_LAP_COUNT: DataType =
DataType("Swim Lap Count", TimeType.INTERVAL, Value.FORMAT_LONG)
/** The current rep count of the exercise in `long` format. */
@JvmField
public val REP_COUNT: DataType = DataType("Rep Count", TimeType.INTERVAL, Value.FORMAT_LONG)
/**
* The total step count over a day in `long` format, where the previous day ends and a new
* day begins at 12:00 AM local time. Each DataPoint of this type will cover the interval
* from the start of day to now. In the event of time-zone shifts, the interval might be
* greater than 24hrs.
*/
@JvmField
public val DAILY_STEPS: DataType =
DataType("Daily Steps", TimeType.INTERVAL, Value.FORMAT_LONG)
/**
* The total number floors climbed over a day in `double` format, where the previous day
* ends and a new day begins at 12:00 AM local time. Each DataPoint of this type will cover
* the interval from the start of day to now. In the event of time-zone shifts, the interval
* might be greater than 24hrs.
*/
@JvmField
public val DAILY_FLOORS: DataType =
DataType("Daily Floors", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/**
* The total number calories over a day in `double` format, where the previous day ends and
* a new day begins at 12:00 AM local time. Each DataPoint of this type will cover the
* interval from the start of day to now. In the event of time-zone shifts, the interval
* might be greater than 24hrs.
*/
@JvmField
public val DAILY_CALORIES: DataType =
DataType("Daily Calories", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
/**
* The total distance over a day in `double` format, where the previous day ends and a new
* day begins at 12:00 AM local time. Each DataPoint of this type will cover the interval
* from the start of day to now. In the event of time-zone shifts, the interval might be
* greater than 24hrs.
*/
@JvmField
public val DAILY_DISTANCE: DataType =
DataType("Daily Distance", TimeType.INTERVAL, Value.FORMAT_DOUBLE)
}
}