Drop from 04-25

Test: :health:health-data-client:test
Change-Id: Ibdd203db34e6ad14f137491734249ef9ca8c83fc
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt
index 789386b..cafd3ce 100644
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt
@@ -30,7 +30,7 @@
 import androidx.health.connect.client.records.BoneMass
 import androidx.health.connect.client.records.CervicalMucus
 import androidx.health.connect.client.records.CervicalPosition
-import androidx.health.connect.client.records.CyclingPedalingCadence
+import androidx.health.connect.client.records.CyclingPedalingCadenceSeries
 import androidx.health.connect.client.records.Distance
 import androidx.health.connect.client.records.ElevationGained
 import androidx.health.connect.client.records.FloorsClimbed
@@ -52,7 +52,7 @@
 import androidx.health.connect.client.records.Nutrition
 import androidx.health.connect.client.records.OvulationTest
 import androidx.health.connect.client.records.OxygenSaturation
-import androidx.health.connect.client.records.Power
+import androidx.health.connect.client.records.PowerSeries
 import androidx.health.connect.client.records.Record
 import androidx.health.connect.client.records.Repetitions
 import androidx.health.connect.client.records.RespiratoryRate
@@ -60,9 +60,9 @@
 import androidx.health.connect.client.records.SexualActivity
 import androidx.health.connect.client.records.SleepSession
 import androidx.health.connect.client.records.SleepStage
-import androidx.health.connect.client.records.Speed
+import androidx.health.connect.client.records.SpeedSeries
 import androidx.health.connect.client.records.Steps
-import androidx.health.connect.client.records.StepsCadence
+import androidx.health.connect.client.records.StepsCadenceSeries
 import androidx.health.connect.client.records.SwimmingStrokes
 import androidx.health.connect.client.records.TotalCaloriesBurned
 import androidx.health.connect.client.records.TotalEnergyBurned
@@ -89,7 +89,7 @@
         BoneMass::class,
         CervicalMucus::class,
         CervicalPosition::class,
-        CyclingPedalingCadence::class,
+        CyclingPedalingCadenceSeries::class,
         Distance::class,
         ElevationGained::class,
         FloorsClimbed::class,
@@ -111,16 +111,16 @@
         Nutrition::class,
         OvulationTest::class,
         OxygenSaturation::class,
-        Power::class,
+        PowerSeries::class,
         Repetitions::class,
         RespiratoryRate::class,
         RestingHeartRate::class,
         SexualActivity::class,
         SleepSession::class,
         SleepStage::class,
-        Speed::class,
+        SpeedSeries::class,
         Steps::class,
-        StepsCadence::class,
+        StepsCadenceSeries::class,
         SwimmingStrokes::class,
         TotalCaloriesBurned::class,
         TotalEnergyBurned::class,
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt
index 4eb318e..62b8de4 100644
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt
@@ -31,6 +31,7 @@
 import androidx.health.connect.client.records.CervicalMucus
 import androidx.health.connect.client.records.CervicalPosition
 import androidx.health.connect.client.records.CyclingPedalingCadence
+import androidx.health.connect.client.records.CyclingPedalingCadenceSeries
 import androidx.health.connect.client.records.Distance
 import androidx.health.connect.client.records.ElevationGained
 import androidx.health.connect.client.records.FloorsClimbed
@@ -54,6 +55,7 @@
 import androidx.health.connect.client.records.OvulationTest
 import androidx.health.connect.client.records.OxygenSaturation
 import androidx.health.connect.client.records.Power
+import androidx.health.connect.client.records.PowerSeries
 import androidx.health.connect.client.records.Record
 import androidx.health.connect.client.records.Repetitions
 import androidx.health.connect.client.records.RespiratoryRate
@@ -62,8 +64,10 @@
 import androidx.health.connect.client.records.SleepSession
 import androidx.health.connect.client.records.SleepStage
 import androidx.health.connect.client.records.Speed
+import androidx.health.connect.client.records.SpeedSeries
 import androidx.health.connect.client.records.Steps
 import androidx.health.connect.client.records.StepsCadence
+import androidx.health.connect.client.records.StepsCadenceSeries
 import androidx.health.connect.client.records.SwimmingStrokes
 import androidx.health.connect.client.records.TotalCaloriesBurned
 import androidx.health.connect.client.records.TotalEnergyBurned
@@ -159,12 +163,20 @@
                     zoneOffset = zoneOffset,
                     metadata = metadata
                 )
-            "CyclingPedalingCadence" ->
-                CyclingPedalingCadence(
-                    revolutionsPerMinute = getDouble("rpm"),
-                    time = time,
-                    zoneOffset = zoneOffset,
-                    metadata = metadata
+            "CyclingPedalingCadenceSeries" ->
+                CyclingPedalingCadenceSeries(
+                    startTime = startTime,
+                    startZoneOffset = startZoneOffset,
+                    endTime = endTime,
+                    endZoneOffset = endZoneOffset,
+                    samples =
+                        seriesValuesList.map { value ->
+                            CyclingPedalingCadence(
+                                time = Instant.ofEpochMilli(value.instantTimeMillis),
+                                revolutionsPerMinute = value.getDouble("rpm"),
+                            )
+                        },
+                    metadata = metadata,
                 )
             "HeartRateSeries" ->
                 HeartRateSeries(
@@ -286,12 +298,20 @@
                     zoneOffset = zoneOffset,
                     metadata = metadata
                 )
-            "Power" ->
-                Power(
-                    power = getDouble("power"),
-                    time = time,
-                    zoneOffset = zoneOffset,
-                    metadata = metadata
+            "PowerSeries" ->
+                PowerSeries(
+                    startTime = startTime,
+                    startZoneOffset = startZoneOffset,
+                    endTime = endTime,
+                    endZoneOffset = endZoneOffset,
+                    samples =
+                        seriesValuesList.map { value ->
+                            Power(
+                                time = Instant.ofEpochMilli(value.instantTimeMillis),
+                                watts = value.getDouble("power"),
+                            )
+                        },
+                    metadata = metadata,
                 )
             "RespiratoryRate" ->
                 RespiratoryRate(
@@ -314,19 +334,35 @@
                     zoneOffset = zoneOffset,
                     metadata = metadata
                 )
-            "Speed" ->
-                Speed(
-                    speedMetersPerSecond = getDouble("speed"),
-                    time = time,
-                    zoneOffset = zoneOffset,
-                    metadata = metadata
+            "SpeedSeries" ->
+                SpeedSeries(
+                    startTime = startTime,
+                    startZoneOffset = startZoneOffset,
+                    endTime = endTime,
+                    endZoneOffset = endZoneOffset,
+                    samples =
+                        seriesValuesList.map { value ->
+                            Speed(
+                                time = Instant.ofEpochMilli(value.instantTimeMillis),
+                                metersPerSecond = value.getDouble("speed"),
+                            )
+                        },
+                    metadata = metadata,
                 )
-            "StepsCadence" ->
-                StepsCadence(
-                    rate = getDouble("rate"),
-                    time = time,
-                    zoneOffset = zoneOffset,
-                    metadata = metadata
+            "StepsCadenceSeries" ->
+                StepsCadenceSeries(
+                    startTime = startTime,
+                    startZoneOffset = startZoneOffset,
+                    endTime = endTime,
+                    endZoneOffset = endZoneOffset,
+                    samples =
+                        seriesValuesList.map { value ->
+                            StepsCadence(
+                                time = Instant.ofEpochMilli(value.instantTimeMillis),
+                                rate = value.getDouble("rate"),
+                            )
+                        },
+                    metadata = metadata,
                 )
             "Vo2Max" ->
                 Vo2Max(
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt
index 02b3c01..0038280 100644
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt
@@ -30,7 +30,7 @@
 import androidx.health.connect.client.records.BoneMass
 import androidx.health.connect.client.records.CervicalMucus
 import androidx.health.connect.client.records.CervicalPosition
-import androidx.health.connect.client.records.CyclingPedalingCadence
+import androidx.health.connect.client.records.CyclingPedalingCadenceSeries
 import androidx.health.connect.client.records.Distance
 import androidx.health.connect.client.records.ElevationGained
 import androidx.health.connect.client.records.FloorsClimbed
@@ -52,7 +52,7 @@
 import androidx.health.connect.client.records.Nutrition
 import androidx.health.connect.client.records.OvulationTest
 import androidx.health.connect.client.records.OxygenSaturation
-import androidx.health.connect.client.records.Power
+import androidx.health.connect.client.records.PowerSeries
 import androidx.health.connect.client.records.Record
 import androidx.health.connect.client.records.Repetitions
 import androidx.health.connect.client.records.RespiratoryRate
@@ -61,9 +61,9 @@
 import androidx.health.connect.client.records.SexualActivity
 import androidx.health.connect.client.records.SleepSession
 import androidx.health.connect.client.records.SleepStage
-import androidx.health.connect.client.records.Speed
+import androidx.health.connect.client.records.SpeedSeries
 import androidx.health.connect.client.records.Steps
-import androidx.health.connect.client.records.StepsCadence
+import androidx.health.connect.client.records.StepsCadenceSeries
 import androidx.health.connect.client.records.SwimmingStrokes
 import androidx.health.connect.client.records.TotalCaloriesBurned
 import androidx.health.connect.client.records.TotalEnergyBurned
@@ -149,11 +149,13 @@
                     firmness?.let { putValues("firmness", enumVal(it)) }
                 }
                 .build()
-        is CyclingPedalingCadence ->
-            instantaneousProto()
-                .setDataType(protoDataType("CyclingPedalingCadence"))
-                .apply { putValues("rpm", doubleVal(revolutionsPerMinute)) }
-                .build()
+        is CyclingPedalingCadenceSeries ->
+            toProto(dataTypeName = "CyclingPedalingCadenceSeries") { sample ->
+                DataProto.SeriesValue.newBuilder()
+                    .putValues("rpm", doubleVal(sample.revolutionsPerMinute))
+                    .setInstantTimeMillis(sample.time.toEpochMilli())
+                    .build()
+            }
         is HeartRateSeries ->
             toProto(dataTypeName = "HeartRateSeries") { sample ->
                 DataProto.SeriesValue.newBuilder()
@@ -236,11 +238,13 @@
                 .setDataType(protoDataType("OxygenSaturation"))
                 .apply { putValues("percentage", doubleVal(percentage)) }
                 .build()
-        is Power ->
-            instantaneousProto()
-                .setDataType(protoDataType("Power"))
-                .apply { putValues("power", doubleVal(power)) }
-                .build()
+        is PowerSeries ->
+            toProto(dataTypeName = "PowerSeries") { sample ->
+                DataProto.SeriesValue.newBuilder()
+                    .putValues("power", doubleVal(sample.watts))
+                    .setInstantTimeMillis(sample.time.toEpochMilli())
+                    .build()
+            }
         is RespiratoryRate ->
             instantaneousProto()
                 .setDataType(protoDataType("RespiratoryRate"))
@@ -256,16 +260,20 @@
                 .setDataType(protoDataType("SexualActivity"))
                 .apply { protectionUsed?.let { putValues("protectionUsed", enumVal(it)) } }
                 .build()
-        is Speed ->
-            instantaneousProto()
-                .setDataType(protoDataType("Speed"))
-                .apply { putValues("speed", doubleVal(speedMetersPerSecond)) }
-                .build()
-        is StepsCadence ->
-            instantaneousProto()
-                .setDataType(protoDataType("StepsCadence"))
-                .apply { putValues("rate", doubleVal(rate)) }
-                .build()
+        is SpeedSeries ->
+            toProto(dataTypeName = "SpeedSeries") { sample ->
+                DataProto.SeriesValue.newBuilder()
+                    .putValues("speed", doubleVal(sample.metersPerSecond))
+                    .setInstantTimeMillis(sample.time.toEpochMilli())
+                    .build()
+            }
+        is StepsCadenceSeries ->
+            toProto(dataTypeName = "StepsCadenceSeries") { sample ->
+                DataProto.SeriesValue.newBuilder()
+                    .putValues("rate", doubleVal(sample.rate))
+                    .setInstantTimeMillis(sample.time.toEpochMilli())
+                    .build()
+            }
         is Vo2Max ->
             instantaneousProto()
                 .setDataType(protoDataType("Vo2Max"))
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/CyclingPedalingCadence.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/CyclingPedalingCadence.kt
deleted file mode 100644
index a66cf182..0000000
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/CyclingPedalingCadence.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 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.connect.client.records
-
-import androidx.annotation.RestrictTo
-import androidx.health.connect.client.metadata.Metadata
-import java.time.Instant
-import java.time.ZoneOffset
-
-/**
- * If a user goes cycling, this can be used to capture their pedaling rate, in crank revolutions per
- * minute (RPM). Each record represents a single instantaneous measurement.
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-public class CyclingPedalingCadence(
-    /** Cycling revolutions per minute. Required field. Valid range: 0-10000. */
-    public val revolutionsPerMinute: Double,
-    override val time: Instant,
-    override val zoneOffset: ZoneOffset?,
-    override val metadata: Metadata = Metadata.EMPTY,
-) : InstantaneousRecord {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other !is CyclingPedalingCadence) return false
-
-        if (revolutionsPerMinute != other.revolutionsPerMinute) return false
-        if (time != other.time) return false
-        if (zoneOffset != other.zoneOffset) return false
-        if (metadata != other.metadata) return false
-
-        return true
-    }
-
-    override fun hashCode(): Int {
-        var result = 0
-        result = 31 * result + revolutionsPerMinute.hashCode()
-        result = 31 * result + time.hashCode()
-        result = 31 * result + (zoneOffset?.hashCode() ?: 0)
-        result = 31 * result + metadata.hashCode()
-        return result
-    }
-}
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/CyclingPedalingCadenceSeries.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/CyclingPedalingCadenceSeries.kt
new file mode 100644
index 0000000..6119e1d
--- /dev/null
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/CyclingPedalingCadenceSeries.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2022 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.connect.client.records
+
+import androidx.annotation.RestrictTo
+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.metadata.Metadata
+import java.time.Instant
+import java.time.ZoneOffset
+
+/**
+ * Captures the user's cycling pedaling cadence. Each record represents a series of measurements.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public class CyclingPedalingCadenceSeries(
+    override val startTime: Instant,
+    override val startZoneOffset: ZoneOffset?,
+    override val endTime: Instant,
+    override val endZoneOffset: ZoneOffset?,
+    override val samples: List<CyclingPedalingCadence>,
+    override val metadata: Metadata = Metadata.EMPTY,
+) : SeriesRecord<CyclingPedalingCadence> {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is CyclingPedalingCadenceSeries) return false
+
+        if (startTime != other.startTime) return false
+        if (startZoneOffset != other.startZoneOffset) return false
+        if (endTime != other.endTime) return false
+        if (endZoneOffset != other.endZoneOffset) return false
+        if (samples != other.samples) return false
+        if (metadata != other.metadata) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = startTime.hashCode()
+        result = 31 * result + (startZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + endTime.hashCode()
+        result = 31 * result + (endZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + samples.hashCode()
+        result = 31 * result + metadata.hashCode()
+        return result
+    }
+
+    internal companion object {
+        private const val TYPE = "CyclingPedalingCadence"
+        private const val RPM_FIELD = "rpm"
+
+        /**
+         * Metric identifier to retrieve average heart rate from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val RPM_AVG: AggregateMetric<Double> = doubleMetric(TYPE, AVERAGE, RPM_FIELD)
+
+        /**
+         * Metric identifier to retrieve minimum heart rate from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val RPM_MIN: AggregateMetric<Double> = doubleMetric(TYPE, MINIMUM, RPM_FIELD)
+
+        /**
+         * Metric identifier to retrieve maximum heart rate from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val RPM_MAX: AggregateMetric<Double> = doubleMetric(TYPE, MAXIMUM, RPM_FIELD)
+    }
+}
+
+/**
+ * Represents a single measurement of the cycling pedaling cadence.
+ *
+ * @param time The point in time when the measurement was taken.
+ * @param revolutionsPerMinute Cycling revolutions per minute. Valid range: 0-10000.
+ *
+ * @see CyclingPedalingCadenceSeries
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public class CyclingPedalingCadence(
+    val time: Instant,
+    val revolutionsPerMinute: Double,
+) {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is CyclingPedalingCadence) return false
+
+        if (time != other.time) return false
+        if (revolutionsPerMinute != other.revolutionsPerMinute) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = time.hashCode()
+        result = 31 * result + revolutionsPerMinute.hashCode()
+        return result
+    }
+}
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/HeartRateSeries.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/HeartRateSeries.kt
index 95201d1..3f7b72c 100644
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/HeartRateSeries.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/HeartRateSeries.kt
@@ -96,7 +96,10 @@
 /**
  * Represents a single measurement of the heart rate.
  *
+ * @param time The point in time when the measurement was taken.
  * @param beatsPerMinute Heart beats per minute. Validation range: 1-300.
+ *
+ * @see HeartRateSeries
  */
 public class HeartRate(
     val time: Instant,
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/Power.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/Power.kt
deleted file mode 100644
index 7b69957..0000000
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/Power.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2022 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.connect.client.records
-
-import androidx.annotation.RestrictTo
-import androidx.health.connect.client.metadata.Metadata
-import java.time.Instant
-import java.time.ZoneOffset
-
-/**
- * Captures the power generated by a user when doing an activity, measured in watts. For example,
- * using a power meter when exercising on a stationary bike. Each record represents an instantaneous
- * measurement of power generated.
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-public class Power(
-    /** Power generated, in watts. Required field. Valid range: 0-100000. */
-    public val power: Double,
-    override val time: Instant,
-    override val zoneOffset: ZoneOffset?,
-    override val metadata: Metadata = Metadata.EMPTY,
-) : InstantaneousRecord {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other !is Power) return false
-
-        if (power != other.power) return false
-        if (time != other.time) return false
-        if (zoneOffset != other.zoneOffset) return false
-        if (metadata != other.metadata) return false
-
-        return true
-    }
-
-    override fun hashCode(): Int {
-        var result = 0
-        result = 31 * result + power.hashCode()
-        result = 31 * result + time.hashCode()
-        result = 31 * result + (zoneOffset?.hashCode() ?: 0)
-        result = 31 * result + metadata.hashCode()
-        return result
-    }
-}
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/PowerSeries.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/PowerSeries.kt
new file mode 100644
index 0000000..a3753d1
--- /dev/null
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/PowerSeries.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 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.connect.client.records
+
+import androidx.annotation.RestrictTo
+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.metadata.Metadata
+import java.time.Instant
+import java.time.ZoneOffset
+
+/** Captures the power generated by the user. Each record represents a series of measurements. */
+@RestrictTo(RestrictTo.Scope.LIBRARY) // Will be made public after API reviews
+public class PowerSeries(
+    override val startTime: Instant,
+    override val startZoneOffset: ZoneOffset?,
+    override val endTime: Instant,
+    override val endZoneOffset: ZoneOffset?,
+    override val samples: List<Power>,
+    override val metadata: Metadata = Metadata.EMPTY,
+) : SeriesRecord<Power> {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is PowerSeries) return false
+
+        if (startTime != other.startTime) return false
+        if (startZoneOffset != other.startZoneOffset) return false
+        if (endTime != other.endTime) return false
+        if (endZoneOffset != other.endZoneOffset) return false
+        if (samples != other.samples) return false
+        if (metadata != other.metadata) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = startTime.hashCode()
+        result = 31 * result + (startZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + endTime.hashCode()
+        result = 31 * result + (endZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + samples.hashCode()
+        result = 31 * result + metadata.hashCode()
+        return result
+    }
+
+    internal companion object {
+        private const val TYPE = "Power"
+        private const val POWER_FIELD = "power"
+
+        /**
+         * Metric identifier to retrieve average heart rate from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val WATTS_AVG: AggregateMetric<Double> = doubleMetric(TYPE, AVERAGE, POWER_FIELD)
+
+        /**
+         * Metric identifier to retrieve minimum heart rate from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val WATTS_MIN: AggregateMetric<Double> = doubleMetric(TYPE, MINIMUM, POWER_FIELD)
+
+        /**
+         * Metric identifier to retrieve maximum heart rate from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val WATTS_MAX: AggregateMetric<Double> = doubleMetric(TYPE, MAXIMUM, POWER_FIELD)
+    }
+}
+
+/**
+ * Represents a single measurement of power. For example, using a power meter when exercising on a
+ * stationary bike.
+ *
+ * @param time The point in time when the measurement was taken.
+ * @param watts Power generated, in watts. Valid range: 0-100000.
+ *
+ * @see PowerSeries
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY) // Will be made public after API reviews
+public class Power(
+    val time: Instant,
+    val watts: Double,
+) {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is Power) return false
+
+        if (time != other.time) return false
+        if (watts != other.watts) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = time.hashCode()
+        result = 31 * result + watts.hashCode()
+        return result
+    }
+}
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/RepetitionActivityTypes.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/RepetitionActivityTypes.kt
index 0e75226..c537f34c 100644
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/RepetitionActivityTypes.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/RepetitionActivityTypes.kt
@@ -90,7 +90,8 @@
             RepetitionActivityTypes.SHOULDER_PRESS,
             RepetitionActivityTypes.SINGLE_ARM_TRICEPS_EXTENSION,
             RepetitionActivityTypes.SIT_UP,
-            RepetitionActivityTypes.SQUAT]
+            RepetitionActivityTypes.SQUAT
+        ]
 )
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 annotation class RepetitionActivityType
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/Speed.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/Speed.kt
deleted file mode 100644
index 6e5e345..0000000
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/Speed.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2022 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.connect.client.records
-
-import androidx.annotation.RestrictTo
-import androidx.health.connect.client.aggregate.AggregateMetric
-import androidx.health.connect.client.metadata.Metadata
-import java.time.Instant
-import java.time.ZoneOffset
-
-/**
- * Captures the user's speed in meters per second. The value represents the scalar magnitude of the
- * speed, so negative values should not occur. Each record represents a single instantaneous
- * measurement.
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-public class Speed(
-    /** Speed in meters per second. Required field. Valid range: 0-1000000. */
-    public val speedMetersPerSecond: Double,
-    override val time: Instant,
-    override val zoneOffset: ZoneOffset?,
-    override val metadata: Metadata = Metadata.EMPTY,
-) : InstantaneousRecord {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other !is Speed) return false
-
-        if (speedMetersPerSecond != other.speedMetersPerSecond) return false
-        if (time != other.time) return false
-        if (zoneOffset != other.zoneOffset) return false
-        if (metadata != other.metadata) return false
-
-        return true
-    }
-
-    override fun hashCode(): Int {
-        var result = 0
-        result = 31 * result + speedMetersPerSecond.hashCode()
-        result = 31 * result + time.hashCode()
-        result = 31 * result + (zoneOffset?.hashCode() ?: 0)
-        result = 31 * result + metadata.hashCode()
-        return result
-    }
-
-    companion object {
-        private const val SPEED_NAME = "Speed"
-        private const val SPEED_FIELD_NAME = "speed"
-
-        /**
-         * Metric identifier to retrieve average speed from
-         * [androidx.health.connect.client.aggregate.AggregationResult].
-         */
-        @JvmField
-        val AVG: AggregateMetric<Double> =
-            AggregateMetric.doubleMetric(
-                SPEED_NAME,
-                AggregateMetric.AggregationType.AVERAGE,
-                SPEED_FIELD_NAME
-            )
-
-        /**
-         * Metric identifier to retrieve minimum speed from
-         * [androidx.health.connect.client.aggregate.AggregationResult].
-         */
-        @JvmField
-        val MIN: AggregateMetric<Double> =
-            AggregateMetric.doubleMetric(
-                SPEED_NAME,
-                AggregateMetric.AggregationType.MINIMUM,
-                SPEED_FIELD_NAME
-            )
-
-        /**
-         * Metric identifier to retrieve maximum speed from
-         * [androidx.health.connect.client.aggregate.AggregationResult].
-         */
-        @JvmField
-        val MAX: AggregateMetric<Double> =
-            AggregateMetric.doubleMetric(
-                SPEED_NAME,
-                AggregateMetric.AggregationType.MAXIMUM,
-                SPEED_FIELD_NAME
-            )
-    }
-}
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/SpeedSeries.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/SpeedSeries.kt
new file mode 100644
index 0000000..fd657d2
--- /dev/null
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/SpeedSeries.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 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.connect.client.records
+
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.aggregate.AggregateMetric
+import androidx.health.connect.client.metadata.Metadata
+import java.time.Instant
+import java.time.ZoneOffset
+
+/** Captures the user's speed. Each record represents a series of measurements. */
+@RestrictTo(RestrictTo.Scope.LIBRARY) // Will be made public after API reviews
+public class SpeedSeries(
+    override val startTime: Instant,
+    override val startZoneOffset: ZoneOffset?,
+    override val endTime: Instant,
+    override val endZoneOffset: ZoneOffset?,
+    override val samples: List<Speed>,
+    override val metadata: Metadata = Metadata.EMPTY,
+) : SeriesRecord<Speed> {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is SpeedSeries) return false
+
+        if (startTime != other.startTime) return false
+        if (startZoneOffset != other.startZoneOffset) return false
+        if (endTime != other.endTime) return false
+        if (endZoneOffset != other.endZoneOffset) return false
+        if (samples != other.samples) return false
+        if (metadata != other.metadata) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = startTime.hashCode()
+        result = 31 * result + (startZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + endTime.hashCode()
+        result = 31 * result + (endZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + samples.hashCode()
+        result = 31 * result + metadata.hashCode()
+        return result
+    }
+
+    internal companion object {
+        private const val SPEED_TYPE_NAME = "Speed"
+        private const val SPEED_FIELD_NAME = "speed"
+
+        /**
+         * Metric identifier to retrieve average speed from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val AVG: AggregateMetric<Double> =
+            AggregateMetric.doubleMetric(
+                SPEED_TYPE_NAME,
+                AggregateMetric.AggregationType.AVERAGE,
+                SPEED_FIELD_NAME
+            )
+
+        /**
+         * Metric identifier to retrieve minimum speed from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val MIN: AggregateMetric<Double> =
+            AggregateMetric.doubleMetric(
+                SPEED_TYPE_NAME,
+                AggregateMetric.AggregationType.MINIMUM,
+                SPEED_FIELD_NAME
+            )
+
+        /**
+         * Metric identifier to retrieve maximum speed from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val MAX: AggregateMetric<Double> =
+            AggregateMetric.doubleMetric(
+                SPEED_TYPE_NAME,
+                AggregateMetric.AggregationType.MAXIMUM,
+                SPEED_FIELD_NAME
+            )
+    }
+}
+
+/**
+ * Represents a single measurement of the speed, a scalar magnitude.
+ *
+ * @param time The point in time when the measurement was taken.
+ * @param metersPerSecond Speed in meters per second. Valid range: 0-1000000.
+ *
+ * @see SpeedSeries
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY) // Will be made public after API reviews
+public class Speed(
+    val time: Instant,
+    val metersPerSecond: Double,
+) {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is Speed) return false
+
+        if (time != other.time) return false
+        if (metersPerSecond != other.metersPerSecond) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = time.hashCode()
+        result = 31 * result + metersPerSecond.hashCode()
+        return result
+    }
+}
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/StepsCadence.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/StepsCadence.kt
deleted file mode 100644
index 894619e..0000000
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/StepsCadence.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 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.connect.client.records
-
-import androidx.annotation.RestrictTo
-import androidx.health.connect.client.metadata.Metadata
-import java.time.Instant
-import java.time.ZoneOffset
-
-/**
- * Captures the step cadence, measured in steps per minute. Each record represents an instantaneous
- * measurement of the cadence in steps per minute.
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-public class StepsCadence(
-    /** Rate in steps count per minute. Required field. Valid range: 0-10000. */
-    public val rate: Double,
-    override val time: Instant,
-    override val zoneOffset: ZoneOffset?,
-    override val metadata: Metadata = Metadata.EMPTY,
-) : InstantaneousRecord {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other !is StepsCadence) return false
-
-        if (rate != other.rate) return false
-        if (time != other.time) return false
-        if (zoneOffset != other.zoneOffset) return false
-        if (metadata != other.metadata) return false
-
-        return true
-    }
-
-    override fun hashCode(): Int {
-        var result = 0
-        result = 31 * result + rate.hashCode()
-        result = 31 * result + time.hashCode()
-        result = 31 * result + (zoneOffset?.hashCode() ?: 0)
-        result = 31 * result + metadata.hashCode()
-        return result
-    }
-}
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/records/StepsCadenceSeries.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/StepsCadenceSeries.kt
new file mode 100644
index 0000000..2f078c5
--- /dev/null
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/records/StepsCadenceSeries.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 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.connect.client.records
+
+import androidx.annotation.RestrictTo
+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.metadata.Metadata
+import java.time.Instant
+import java.time.ZoneOffset
+
+/** Captures the user's steps cadence. Each record represents a series of measurements. */
+@RestrictTo(RestrictTo.Scope.LIBRARY) // Will be made public after API reviews
+class StepsCadenceSeries(
+    override val startTime: Instant,
+    override val startZoneOffset: ZoneOffset?,
+    override val endTime: Instant,
+    override val endZoneOffset: ZoneOffset?,
+    override val samples: List<StepsCadence>,
+    override val metadata: Metadata = Metadata.EMPTY,
+) : SeriesRecord<StepsCadence> {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is StepsCadenceSeries) return false
+
+        if (startTime != other.startTime) return false
+        if (startZoneOffset != other.startZoneOffset) return false
+        if (endTime != other.endTime) return false
+        if (endZoneOffset != other.endZoneOffset) return false
+        if (samples != other.samples) return false
+        if (metadata != other.metadata) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = startTime.hashCode()
+        result = 31 * result + (startZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + endTime.hashCode()
+        result = 31 * result + (endZoneOffset?.hashCode() ?: 0)
+        result = 31 * result + samples.hashCode()
+        result = 31 * result + metadata.hashCode()
+        return result
+    }
+
+    internal companion object {
+        private const val TYPE = "StepsCadence"
+        private const val RATE_FIELD = "rate"
+
+        /**
+         * Metric identifier to retrieve average speed from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val RATE_AVG: AggregateMetric<Double> = doubleMetric(TYPE, AVERAGE, RATE_FIELD)
+
+        /**
+         * Metric identifier to retrieve minimum speed from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val RATE_MIN: AggregateMetric<Double> = doubleMetric(TYPE, MINIMUM, RATE_FIELD)
+
+        /**
+         * Metric identifier to retrieve maximum speed from
+         * [androidx.health.connect.client.aggregate.AggregationResult].
+         */
+        @JvmField
+        internal val RATE_MAX: AggregateMetric<Double> = doubleMetric(TYPE, MAXIMUM, RATE_FIELD)
+    }
+}
+
+/**
+ * Represents a single measurement of the steps cadence.
+ *
+ * @param time The point in time when the measurement was taken.
+ * @param rate Rate in steps count per minute. Valid range: 0-10000.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY) // Will be made public after API reviews
+class StepsCadence(
+    val time: Instant,
+    val rate: Double,
+) {
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is StepsCadence) return false
+
+        if (time != other.time) return false
+        if (rate != other.rate) return false
+
+        return true
+    }
+
+    /*
+     * Generated by the IDE: Code -> Generate -> "equals() and hashCode()".
+     */
+    override fun hashCode(): Int {
+        var result = time.hashCode()
+        result = 31 * result + rate.hashCode()
+        return result
+    }
+}
diff --git a/health/health-connect-client/src/main/java/androidx/health/platform/client/error/ErrorStatus.kt b/health/health-connect-client/src/main/java/androidx/health/platform/client/error/ErrorStatus.kt
index e70fffa..658ad48c 100644
--- a/health/health-connect-client/src/main/java/androidx/health/platform/client/error/ErrorStatus.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/platform/client/error/ErrorStatus.kt
@@ -45,8 +45,7 @@
         @ErrorCode
         fun safeErrorCode(errorCode: Int): Int {
             return ErrorCode::class
-                .java
-                .declaredFields
+                .java.declaredFields
                 .filter { it.type.isAssignableFrom(Int::class.java) }
                 .map { field: Field ->
                     try {
diff --git a/health/health-connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt b/health/health-connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt
index 334d41f..c4aa309 100644
--- a/health/health-connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt
+++ b/health/health-connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt
@@ -39,6 +39,7 @@
 import androidx.health.connect.client.records.CervicalMucusTextures
 import androidx.health.connect.client.records.CervicalPosition
 import androidx.health.connect.client.records.CyclingPedalingCadence
+import androidx.health.connect.client.records.CyclingPedalingCadenceSeries
 import androidx.health.connect.client.records.Distance
 import androidx.health.connect.client.records.ElevationGained
 import androidx.health.connect.client.records.FloorsClimbed
@@ -64,6 +65,7 @@
 import androidx.health.connect.client.records.OvulationTestResults
 import androidx.health.connect.client.records.OxygenSaturation
 import androidx.health.connect.client.records.Power
+import androidx.health.connect.client.records.PowerSeries
 import androidx.health.connect.client.records.RepetitionActivityTypes
 import androidx.health.connect.client.records.Repetitions
 import androidx.health.connect.client.records.RespiratoryRate
@@ -73,8 +75,10 @@
 import androidx.health.connect.client.records.SleepStage
 import androidx.health.connect.client.records.SleepStageTypes
 import androidx.health.connect.client.records.Speed
+import androidx.health.connect.client.records.SpeedSeries
 import androidx.health.connect.client.records.Steps
 import androidx.health.connect.client.records.StepsCadence
+import androidx.health.connect.client.records.StepsCadenceSeries
 import androidx.health.connect.client.records.SwimmingStrokes
 import androidx.health.connect.client.records.SwimmingTypes
 import androidx.health.connect.client.records.TotalCaloriesBurned
@@ -263,13 +267,25 @@
     }
 
     @Test
-    fun testCyclingPedalingCadence() {
+    fun testCyclingPedalingCadenceSeries() {
         val data =
-            CyclingPedalingCadence(
-                revolutionsPerMinute = 1.0,
-                time = START_TIME,
-                zoneOffset = END_ZONE_OFFSET,
-                metadata = TEST_METADATA
+            CyclingPedalingCadenceSeries(
+                startTime = START_TIME,
+                startZoneOffset = START_ZONE_OFFSET,
+                endTime = END_TIME,
+                endZoneOffset = END_ZONE_OFFSET,
+                samples =
+                    listOf(
+                        CyclingPedalingCadence(
+                            time = START_TIME,
+                            revolutionsPerMinute = 1.0,
+                        ),
+                        CyclingPedalingCadence(
+                            time = START_TIME,
+                            revolutionsPerMinute = 2.0,
+                        ),
+                    ),
+                metadata = TEST_METADATA,
             )
 
         assertThat(toRecord(data.toProto())).isEqualTo(data)
@@ -500,13 +516,25 @@
     }
 
     @Test
-    fun testPower() {
+    fun testPowerSeries() {
         val data =
-            Power(
-                power = 1.0,
-                time = START_TIME,
-                zoneOffset = END_ZONE_OFFSET,
-                metadata = TEST_METADATA
+            PowerSeries(
+                startTime = START_TIME,
+                startZoneOffset = START_ZONE_OFFSET,
+                endTime = END_TIME,
+                endZoneOffset = END_ZONE_OFFSET,
+                samples =
+                    listOf(
+                        Power(
+                            time = START_TIME,
+                            watts = 1.0,
+                        ),
+                        Power(
+                            time = START_TIME,
+                            watts = 2.0,
+                        ),
+                    ),
+                metadata = TEST_METADATA,
             )
 
         assertThat(toRecord(data.toProto())).isEqualTo(data)
@@ -552,26 +580,50 @@
     }
 
     @Test
-    fun testSpeed() {
+    fun testSpeedSeries() {
         val data =
-            Speed(
-                speedMetersPerSecond = 1.0,
-                time = START_TIME,
-                zoneOffset = END_ZONE_OFFSET,
-                metadata = TEST_METADATA
+            SpeedSeries(
+                startTime = START_TIME,
+                startZoneOffset = START_ZONE_OFFSET,
+                endTime = END_TIME,
+                endZoneOffset = END_ZONE_OFFSET,
+                samples =
+                    listOf(
+                        Speed(
+                            time = START_TIME,
+                            metersPerSecond = 1.0,
+                        ),
+                        Speed(
+                            time = START_TIME,
+                            metersPerSecond = 2.0,
+                        ),
+                    ),
+                metadata = TEST_METADATA,
             )
 
         assertThat(toRecord(data.toProto())).isEqualTo(data)
     }
 
     @Test
-    fun testStepsCadence() {
+    fun testStepsCadenceSeries() {
         val data =
-            StepsCadence(
-                rate = 1.0,
-                time = START_TIME,
-                zoneOffset = END_ZONE_OFFSET,
-                metadata = TEST_METADATA
+            StepsCadenceSeries(
+                startTime = START_TIME,
+                startZoneOffset = START_ZONE_OFFSET,
+                endTime = END_TIME,
+                endZoneOffset = END_ZONE_OFFSET,
+                samples =
+                    listOf(
+                        StepsCadence(
+                            time = START_TIME,
+                            rate = 1.0,
+                        ),
+                        StepsCadence(
+                            time = START_TIME,
+                            rate = 2.0,
+                        ),
+                    ),
+                metadata = TEST_METADATA,
             )
 
         assertThat(toRecord(data.toProto())).isEqualTo(data)
diff --git a/health/health-connect-client/src/test/java/androidx/health/platform/client/impl/data/ProtoParcelableTest.kt b/health/health-connect-client/src/test/java/androidx/health/platform/client/impl/data/ProtoParcelableTest.kt
index d175487..7388283 100644
--- a/health/health-connect-client/src/test/java/androidx/health/platform/client/impl/data/ProtoParcelableTest.kt
+++ b/health/health-connect-client/src/test/java/androidx/health/platform/client/impl/data/ProtoParcelableTest.kt
@@ -59,8 +59,8 @@
 
     @Suppress("UNCHECKED_CAST") // Safe to use in test
     val creator =
-        protoParcelable.javaClass.getField("CREATOR").get(protoParcelable) as
-            Parcelable.Creator<TestProtoParcelable>
+        protoParcelable.javaClass.getField("CREATOR").get(protoParcelable)
+            as Parcelable.Creator<TestProtoParcelable>
     return creator.createFromParcel(parcel)
 }