Add SkinTemperature aggregation types.
Test: Added conversion test and tested locally with Api 35.
Relnote: Add SkinTemperature aggregation types.
Bug: 350445998
Change-Id: Ibe1238dd4658f3cd786e3daf0ee37700f91d6643
diff --git a/health/connect/connect-client/api/current.txt b/health/connect/connect-client/api/current.txt
index a7fde6f..59a0825 100644
--- a/health/connect/connect-client/api/current.txt
+++ b/health/connect/connect-client/api/current.txt
@@ -1350,6 +1350,9 @@
field public static final int MEASUREMENT_LOCATION_TOE = 2; // 0x2
field public static final int MEASUREMENT_LOCATION_UNKNOWN = 0; // 0x0
field public static final int MEASUREMENT_LOCATION_WRIST = 3; // 0x3
+ field public static final androidx.health.connect.client.aggregate.AggregateMetric<androidx.health.connect.client.units.TemperatureDelta> TEMPERATURE_DELTA_AVG;
+ field public static final androidx.health.connect.client.aggregate.AggregateMetric<androidx.health.connect.client.units.TemperatureDelta> TEMPERATURE_DELTA_MAX;
+ field public static final androidx.health.connect.client.aggregate.AggregateMetric<androidx.health.connect.client.units.TemperatureDelta> TEMPERATURE_DELTA_MIN;
}
public static final class SkinTemperatureRecord.Companion {
diff --git a/health/connect/connect-client/api/restricted_current.txt b/health/connect/connect-client/api/restricted_current.txt
index 9ea4048..00b08ec 100644
--- a/health/connect/connect-client/api/restricted_current.txt
+++ b/health/connect/connect-client/api/restricted_current.txt
@@ -1373,6 +1373,9 @@
field public static final int MEASUREMENT_LOCATION_TOE = 2; // 0x2
field public static final int MEASUREMENT_LOCATION_UNKNOWN = 0; // 0x0
field public static final int MEASUREMENT_LOCATION_WRIST = 3; // 0x3
+ field public static final androidx.health.connect.client.aggregate.AggregateMetric<androidx.health.connect.client.units.TemperatureDelta> TEMPERATURE_DELTA_AVG;
+ field public static final androidx.health.connect.client.aggregate.AggregateMetric<androidx.health.connect.client.units.TemperatureDelta> TEMPERATURE_DELTA_MAX;
+ field public static final androidx.health.connect.client.aggregate.AggregateMetric<androidx.health.connect.client.units.TemperatureDelta> TEMPERATURE_DELTA_MIN;
}
public static final class SkinTemperatureRecord.Companion {
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/ResponseConvertersTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/ResponseConvertersTest.kt
index a4fed6d..9e1112b 100644
--- a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/ResponseConvertersTest.kt
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/ResponseConvertersTest.kt
@@ -16,6 +16,7 @@
package androidx.health.connect.client.impl.platform.records
+import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.health.connect.datatypes.units.Energy as PlatformEnergy
import android.health.connect.datatypes.units.Length as PlatformLength
@@ -37,6 +38,7 @@
import androidx.health.connect.client.records.HydrationRecord
import androidx.health.connect.client.records.NutritionRecord
import androidx.health.connect.client.records.PowerRecord
+import androidx.health.connect.client.records.SkinTemperatureRecord
import androidx.health.connect.client.records.SpeedRecord
import androidx.health.connect.client.records.WeightRecord
import androidx.health.connect.client.records.metadata.DataOrigin
@@ -204,6 +206,21 @@
assertThat(metricValues).containsExactly(BloodPressureRecord.SYSTOLIC_MAX.metricKey, 120.0)
}
+ @SuppressLint("NewApi") // Api 35 is covered by sdk extension check
+ @Test
+ fun getDoubleMetricValues_convertsTemperatureDeltaToCelsius() {
+ assumeTrue(SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 13)
+ val metricValues =
+ getDoubleMetricValues(
+ mapOf(
+ SkinTemperatureRecord.TEMPERATURE_DELTA_AVG as AggregateMetric<Any> to
+ PlatformTemperatureDelta.fromCelsius(25.0)
+ )
+ )
+ assertThat(metricValues)
+ .containsExactly(SkinTemperatureRecord.TEMPERATURE_DELTA_AVG.metricKey, 25.0)
+ }
+
@Test
fun getDoubleMetricValues_convertsVelocityToMetersPerSecond() {
assumeTrue(SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 10)
@@ -290,6 +307,7 @@
PlatformEnergy.fromCalories(836_800.0),
)
)
+
assertThat(metricValues)
.comparingValuesUsing(tolerance)
.containsExactly(
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/aggregate/AggregationMappings.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/aggregate/AggregationMappings.kt
index 1cc7a38..1b725cf 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/aggregate/AggregationMappings.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/aggregate/AggregationMappings.kt
@@ -19,6 +19,7 @@
package androidx.health.connect.client.impl.platform.aggregate
+import android.annotation.SuppressLint
import android.health.connect.datatypes.ActiveCaloriesBurnedRecord as PlatformActiveCaloriesBurnedRecord
import android.health.connect.datatypes.AggregationType as PlatformAggregateMetric
import android.health.connect.datatypes.BasalMetabolicRateRecord as PlatformBasalMetabolicRateRecord
@@ -49,6 +50,7 @@
import androidx.health.connect.client.impl.platform.records.PlatformExerciseSessionRecord
import androidx.health.connect.client.impl.platform.records.PlatformPressure
import androidx.health.connect.client.impl.platform.records.PlatformRestingHeartRateRecord
+import androidx.health.connect.client.impl.platform.records.PlatformSkinTemperatureRecord
import androidx.health.connect.client.impl.platform.records.PlatformSleepSessionRecord
import androidx.health.connect.client.impl.platform.records.PlatformSpeedRecord
import androidx.health.connect.client.impl.platform.records.PlatformStepsCadenceRecord
@@ -67,6 +69,7 @@
import androidx.health.connect.client.records.NutritionRecord
import androidx.health.connect.client.records.PowerRecord
import androidx.health.connect.client.records.RestingHeartRateRecord
+import androidx.health.connect.client.records.SkinTemperatureRecord
import androidx.health.connect.client.records.SleepSessionRecord
import androidx.health.connect.client.records.SpeedRecord
import androidx.health.connect.client.records.StepsCadenceRecord
@@ -79,6 +82,7 @@
import androidx.health.connect.client.units.Mass
import androidx.health.connect.client.units.Power
import androidx.health.connect.client.units.Pressure
+import androidx.health.connect.client.units.TemperatureDelta
import androidx.health.connect.client.units.Velocity
import androidx.health.connect.client.units.Volume
import java.time.Duration
@@ -235,6 +239,23 @@
}
.toMap()
+@SuppressLint("NewApi") // API 35 is covered by sdk extension check
+internal val TEMPERATURE_DELTA_METRIC_TYPE_MAP:
+ Map<AggregateMetric<TemperatureDelta>, PlatformAggregateMetric<*>> =
+ if (SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 13) {
+ arrayOf(
+ SkinTemperatureRecord.TEMPERATURE_DELTA_AVG to
+ PlatformSkinTemperatureRecord.SKIN_TEMPERATURE_DELTA_AVG,
+ SkinTemperatureRecord.TEMPERATURE_DELTA_MAX to
+ PlatformSkinTemperatureRecord.SKIN_TEMPERATURE_DELTA_MAX,
+ SkinTemperatureRecord.TEMPERATURE_DELTA_MIN to
+ PlatformSkinTemperatureRecord.SKIN_TEMPERATURE_DELTA_MIN
+ )
+ } else {
+ emptyArray()
+ }
+ .toMap()
+
internal val VELOCITY_AGGREGATION_METRIC_TYPE_MAP:
Map<AggregateMetric<Velocity>, PlatformAggregateMetric<PlatformVelocity>> =
if (SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 10) {
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/request/RequestConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/request/RequestConverters.kt
index f2966dd..b12909e 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/request/RequestConverters.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/request/RequestConverters.kt
@@ -39,6 +39,7 @@
import androidx.health.connect.client.impl.platform.aggregate.LONG_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.POWER_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.PRESSURE_AGGREGATION_METRIC_TYPE_MAP
+import androidx.health.connect.client.impl.platform.aggregate.TEMPERATURE_DELTA_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.VELOCITY_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.VOLUME_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.platformMetrics
@@ -149,6 +150,7 @@
?: KILOGRAMS_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
?: POWER_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
?: PRESSURE_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+ ?: TEMPERATURE_DELTA_METRIC_TYPE_MAP[this] as AggregationType<Any>?
?: VELOCITY_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
?: VOLUME_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
?: throw IllegalArgumentException("Unsupported aggregation type $metricKey")
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/ResponseConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/ResponseConverters.kt
index 07c77a4..e23a08e 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/ResponseConverters.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/ResponseConverters.kt
@@ -19,12 +19,15 @@
package androidx.health.connect.client.impl.platform.response
+import android.annotation.SuppressLint
import android.health.connect.AggregateRecordsGroupedByDurationResponse
import android.health.connect.AggregateRecordsGroupedByPeriodResponse
import android.health.connect.AggregateRecordsResponse
import android.health.connect.datatypes.AggregationType
import android.health.connect.datatypes.units.Energy as PlatformEnergy
import android.health.connect.datatypes.units.Volume as PlatformVolume
+import android.os.Build
+import android.os.ext.SdkExtensions
import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
import androidx.annotation.VisibleForTesting
@@ -41,6 +44,7 @@
import androidx.health.connect.client.impl.platform.aggregate.LONG_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.POWER_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.PRESSURE_AGGREGATION_METRIC_TYPE_MAP
+import androidx.health.connect.client.impl.platform.aggregate.TEMPERATURE_DELTA_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.VELOCITY_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.aggregate.VOLUME_AGGREGATION_METRIC_TYPE_MAP
import androidx.health.connect.client.impl.platform.records.PlatformDataOrigin
@@ -48,6 +52,7 @@
import androidx.health.connect.client.impl.platform.records.PlatformMass
import androidx.health.connect.client.impl.platform.records.PlatformPower
import androidx.health.connect.client.impl.platform.records.PlatformPressure
+import androidx.health.connect.client.impl.platform.records.PlatformTemperatureDelta
import androidx.health.connect.client.impl.platform.records.PlatformVelocity
import androidx.health.connect.client.impl.platform.records.toSdkDataOrigin
import androidx.health.connect.client.impl.platform.request.toAggregationType
@@ -126,6 +131,7 @@
}
}
+@SuppressLint("NewApi") // Api 35 covered by sdk extension check
@VisibleForTesting
internal fun getDoubleMetricValues(
metricValueMap: Map<AggregateMetric<Any>, Any>
@@ -155,6 +161,13 @@
in POWER_AGGREGATION_METRIC_TYPE_MAP -> {
this[key.metricKey] = (value as PlatformPower).inWatts
}
+ in TEMPERATURE_DELTA_METRIC_TYPE_MAP -> {
+ require(
+ SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >=
+ 13
+ )
+ this[key.metricKey] = (value as PlatformTemperatureDelta).inCelsius
+ }
in VELOCITY_AGGREGATION_METRIC_TYPE_MAP -> {
this[key.metricKey] = (value as PlatformVelocity).inMetersPerSecond
}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SkinTemperatureRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SkinTemperatureRecord.kt
index 1c3d1ae..31dafc7 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SkinTemperatureRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SkinTemperatureRecord.kt
@@ -18,6 +18,11 @@
import androidx.annotation.IntDef
import androidx.annotation.RestrictTo
import androidx.health.connect.client.HealthConnectFeatures
+import androidx.health.connect.client.aggregate.AggregateMetric
+import androidx.health.connect.client.aggregate.AggregateMetric.AggregationType.AVERAGE
+import androidx.health.connect.client.aggregate.AggregateMetric.AggregationType.MAXIMUM
+import androidx.health.connect.client.aggregate.AggregateMetric.AggregationType.MINIMUM
+import androidx.health.connect.client.aggregate.AggregateMetric.Companion.doubleMetric
import androidx.health.connect.client.records.metadata.Metadata
import androidx.health.connect.client.units.Temperature
import androidx.health.connect.client.units.TemperatureDelta
@@ -118,9 +123,57 @@
}
companion object {
+
+ private const val SKIN_TEMPERATURE_TYPE_NAME = "SkinTemperature"
+ private const val TEMPERATURE_DELTA_FIELD_NAME = "temperatureDelta"
private val MIN_TEMPERATURE = 0.celsius
private val MAX_TEMPERATURE = 100.celsius
+ /**
+ * Metric identifier for retrieving the average skin temperature delta from
+ * [androidx.health.connect.client.aggregate.AggregationResult]. To check if this metric is
+ * available, use [HealthConnectFeatures.getFeatureStatus] with
+ * [HealthConnectFeatures.FEATURE_SKIN_TEMPERATURE] as the argument.
+ */
+ @JvmField
+ val TEMPERATURE_DELTA_AVG: AggregateMetric<TemperatureDelta> =
+ doubleMetric(
+ SKIN_TEMPERATURE_TYPE_NAME,
+ AVERAGE,
+ TEMPERATURE_DELTA_FIELD_NAME,
+ TemperatureDelta::celsius
+ )
+
+ /**
+ * Metric identifier for retrieving the minimum skin temperature delta from
+ * [androidx.health.connect.client.aggregate.AggregationResult]. To check if this metric is
+ * available, use [HealthConnectFeatures.getFeatureStatus] with
+ * [HealthConnectFeatures.FEATURE_SKIN_TEMPERATURE] as the argument.
+ */
+ @JvmField
+ val TEMPERATURE_DELTA_MIN: AggregateMetric<TemperatureDelta> =
+ doubleMetric(
+ SKIN_TEMPERATURE_TYPE_NAME,
+ MINIMUM,
+ TEMPERATURE_DELTA_FIELD_NAME,
+ TemperatureDelta::celsius
+ )
+
+ /**
+ * Metric identifier for retrieving the maximum skin temperature delta from
+ * [androidx.health.connect.client.aggregate.AggregationResult]. To check if this metric is
+ * available, use [HealthConnectFeatures.getFeatureStatus] with
+ * [HealthConnectFeatures.FEATURE_SKIN_TEMPERATURE] as the argument.
+ */
+ @JvmField
+ val TEMPERATURE_DELTA_MAX: AggregateMetric<TemperatureDelta> =
+ doubleMetric(
+ SKIN_TEMPERATURE_TYPE_NAME,
+ MAXIMUM,
+ TEMPERATURE_DELTA_FIELD_NAME,
+ TemperatureDelta::celsius
+ )
+
/** Use this if the location is unknown. */
const val MEASUREMENT_LOCATION_UNKNOWN: Int = 0
/** Skin temperature measurement was taken from finger. */