Merge "Split out Flow.Spotting into its own record type." into androidx-main
diff --git a/health/connect/connect-client/api/current.txt b/health/connect/connect-client/api/current.txt
index 7b2b08d..081ecbd 100644
--- a/health/connect/connect-client/api/current.txt
+++ b/health/connect/connect-client/api/current.txt
@@ -722,23 +722,23 @@
}
public final class MenstruationFlowRecord implements androidx.health.connect.client.records.Record {
- ctor public MenstruationFlowRecord(java.time.Instant time, java.time.ZoneOffset? zoneOffset, optional String? flow, optional androidx.health.connect.client.records.metadata.Metadata metadata);
- method public String? getFlow();
+ ctor public MenstruationFlowRecord(java.time.Instant time, java.time.ZoneOffset? zoneOffset, optional int flow, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ method public int getFlow();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public java.time.Instant getTime();
method public java.time.ZoneOffset? getZoneOffset();
- property public final String? flow;
+ property public final int flow;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public java.time.Instant time;
property public java.time.ZoneOffset? zoneOffset;
+ field public static final androidx.health.connect.client.records.MenstruationFlowRecord.Companion Companion;
+ field public static final int FLOW_HEAVY = 3; // 0x3
+ field public static final int FLOW_LIGHT = 1; // 0x1
+ field public static final int FLOW_MEDIUM = 2; // 0x2
+ field public static final int FLOW_UNKNOWN = 0; // 0x0
}
- public static final class MenstruationFlowRecord.Flow {
- field public static final String HEAVY = "heavy";
- field public static final androidx.health.connect.client.records.MenstruationFlowRecord.Flow INSTANCE;
- field public static final String LIGHT = "light";
- field public static final String MEDIUM = "medium";
- field public static final String SPOTTING = "spotting";
+ public static final class MenstruationFlowRecord.Companion {
}
public final class NutritionRecord implements androidx.health.connect.client.records.Record {
diff --git a/health/connect/connect-client/api/public_plus_experimental_current.txt b/health/connect/connect-client/api/public_plus_experimental_current.txt
index 7b2b08d..081ecbd 100644
--- a/health/connect/connect-client/api/public_plus_experimental_current.txt
+++ b/health/connect/connect-client/api/public_plus_experimental_current.txt
@@ -722,23 +722,23 @@
}
public final class MenstruationFlowRecord implements androidx.health.connect.client.records.Record {
- ctor public MenstruationFlowRecord(java.time.Instant time, java.time.ZoneOffset? zoneOffset, optional String? flow, optional androidx.health.connect.client.records.metadata.Metadata metadata);
- method public String? getFlow();
+ ctor public MenstruationFlowRecord(java.time.Instant time, java.time.ZoneOffset? zoneOffset, optional int flow, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ method public int getFlow();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public java.time.Instant getTime();
method public java.time.ZoneOffset? getZoneOffset();
- property public final String? flow;
+ property public final int flow;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public java.time.Instant time;
property public java.time.ZoneOffset? zoneOffset;
+ field public static final androidx.health.connect.client.records.MenstruationFlowRecord.Companion Companion;
+ field public static final int FLOW_HEAVY = 3; // 0x3
+ field public static final int FLOW_LIGHT = 1; // 0x1
+ field public static final int FLOW_MEDIUM = 2; // 0x2
+ field public static final int FLOW_UNKNOWN = 0; // 0x0
}
- public static final class MenstruationFlowRecord.Flow {
- field public static final String HEAVY = "heavy";
- field public static final androidx.health.connect.client.records.MenstruationFlowRecord.Flow INSTANCE;
- field public static final String LIGHT = "light";
- field public static final String MEDIUM = "medium";
- field public static final String SPOTTING = "spotting";
+ public static final class MenstruationFlowRecord.Companion {
}
public final class NutritionRecord implements androidx.health.connect.client.records.Record {
diff --git a/health/connect/connect-client/api/restricted_current.txt b/health/connect/connect-client/api/restricted_current.txt
index 4cb4ac9..a9c1a0f 100644
--- a/health/connect/connect-client/api/restricted_current.txt
+++ b/health/connect/connect-client/api/restricted_current.txt
@@ -740,23 +740,23 @@
}
public final class MenstruationFlowRecord implements androidx.health.connect.client.records.InstantaneousRecord {
- ctor public MenstruationFlowRecord(java.time.Instant time, java.time.ZoneOffset? zoneOffset, optional String? flow, optional androidx.health.connect.client.records.metadata.Metadata metadata);
- method public String? getFlow();
+ ctor public MenstruationFlowRecord(java.time.Instant time, java.time.ZoneOffset? zoneOffset, optional int flow, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ method public int getFlow();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public java.time.Instant getTime();
method public java.time.ZoneOffset? getZoneOffset();
- property public final String? flow;
+ property public final int flow;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public java.time.Instant time;
property public java.time.ZoneOffset? zoneOffset;
+ field public static final androidx.health.connect.client.records.MenstruationFlowRecord.Companion Companion;
+ field public static final int FLOW_HEAVY = 3; // 0x3
+ field public static final int FLOW_LIGHT = 1; // 0x1
+ field public static final int FLOW_MEDIUM = 2; // 0x2
+ field public static final int FLOW_UNKNOWN = 0; // 0x0
}
- public static final class MenstruationFlowRecord.Flow {
- field public static final String HEAVY = "heavy";
- field public static final androidx.health.connect.client.records.MenstruationFlowRecord.Flow INSTANCE;
- field public static final String LIGHT = "light";
- field public static final String MEDIUM = "medium";
- field public static final String SPOTTING = "spotting";
+ public static final class MenstruationFlowRecord.Companion {
}
public final class NutritionRecord implements androidx.health.connect.client.records.IntervalRecord {
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt
index f5a6f70..6321e59 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/datatype/RecordsTypeNameMap.kt
@@ -49,6 +49,7 @@
import androidx.health.connect.client.records.HeightRecord
import androidx.health.connect.client.records.HipCircumferenceRecord
import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.IntermenstrualBleedingRecord
import androidx.health.connect.client.records.LeanBodyMassRecord
import androidx.health.connect.client.records.MenstruationFlowRecord
import androidx.health.connect.client.records.NutritionRecord
@@ -119,6 +120,7 @@
"SleepSession" to SleepSessionRecord::class,
"SleepStage" to SleepStageRecord::class,
"SpeedSeries" to SpeedRecord::class, // Keep legacy Series suffix
+ "IntermenstrualBleeding" to IntermenstrualBleedingRecord::class,
"Steps" to StepsRecord::class,
"StepsCadenceSeries" to StepsCadenceRecord::class, // Keep legacy Series suffix
"SwimmingStrokes" to SwimmingStrokesRecord::class,
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt
index 80ac8cc..8330756 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordConverters.kt
@@ -52,6 +52,7 @@
import androidx.health.connect.client.records.HeightRecord
import androidx.health.connect.client.records.HipCircumferenceRecord
import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.IntermenstrualBleedingRecord
import androidx.health.connect.client.records.LeanBodyMassRecord
import androidx.health.connect.client.records.MealType
import androidx.health.connect.client.records.MenstruationFlowRecord
@@ -328,7 +329,12 @@
)
"Menstruation" ->
MenstruationFlowRecord(
- flow = getEnum("flow"),
+ flow =
+ mapEnum(
+ "flow",
+ MenstruationFlowRecord.FLOW_TYPE_STRING_TO_INT_MAP,
+ MenstruationFlowRecord.FLOW_UNKNOWN
+ ),
time = time,
zoneOffset = zoneOffset,
metadata = metadata
@@ -630,6 +636,12 @@
endZoneOffset = endZoneOffset,
metadata = metadata
)
+ "IntermenstrualBleeding" ->
+ IntermenstrualBleedingRecord(
+ time = time,
+ zoneOffset = zoneOffset,
+ metadata = metadata
+ )
"Steps" ->
StepsRecord(
count = getLong("count"),
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt
index 575dfc8..aa31176 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/RecordToProtoConverters.kt
@@ -52,6 +52,7 @@
import androidx.health.connect.client.records.HeightRecord
import androidx.health.connect.client.records.HipCircumferenceRecord
import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.IntermenstrualBleedingRecord
import androidx.health.connect.client.records.LeanBodyMassRecord
import androidx.health.connect.client.records.MealType
import androidx.health.connect.client.records.MenstruationFlowRecord
@@ -246,6 +247,8 @@
.setDataType(protoDataType("HeartRateVariabilityTinn"))
.apply { putValues("heartRateVariability", doubleVal(heartRateVariabilityMillis)) }
.build()
+ is IntermenstrualBleedingRecord ->
+ instantaneousProto().setDataType(protoDataType("IntermenstrualBleeding")).build()
is LeanBodyMassRecord ->
instantaneousProto()
.setDataType(protoDataType("LeanBodyMass"))
@@ -254,7 +257,11 @@
is MenstruationFlowRecord ->
instantaneousProto()
.setDataType(protoDataType("Menstruation"))
- .apply { flow?.let { putValues("flow", enumVal(it)) } }
+ .apply {
+ enumValFromInt(flow, MenstruationFlowRecord.FLOW_TYPE_INT_TO_STRING_MAP)?.let {
+ putValues("flow", it)
+ }
+ }
.build()
is OvulationTestRecord ->
instantaneousProto()
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt
index e80113c..2a787eb 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt
@@ -223,6 +223,9 @@
const val READ_HEART_RATE_VARIABILITY =
"android.permission.health.READ_HEART_RATE_VARIABILITY"
@RestrictTo(RestrictTo.Scope.LIBRARY)
+ const val READ_INTERMENSTRUAL_BLEEDING =
+ "android.permission.health.READ_INTERMENSTRUAL_BLEEDING"
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
const val READ_OXYGEN_SATURATION = "android.permission.health.READ_OXYGEN_SATURATION"
@RestrictTo(RestrictTo.Scope.LIBRARY)
const val READ_RESPIRATORY_RATE = "android.permission.health.READ_RESPIRATORY_RATE"
@@ -270,6 +273,9 @@
@RestrictTo(RestrictTo.Scope.LIBRARY)
const val WRITE_HIP_CIRCUMFERENCE = "android.permission.health.WRITE_HIP_CIRCUMFERENCE"
@RestrictTo(RestrictTo.Scope.LIBRARY)
+ const val WRITE_INTERMENSTRUAL_BLEEDING =
+ "android.permission.health.WRITE_INTERMENSTRUAL_BLEEDING"
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
const val WRITE_LEAN_BODY_MASS = "android.permission.health.WRITE_LEAN_BODY_MASS"
@RestrictTo(RestrictTo.Scope.LIBRARY)
const val WRITE_WAIST_CIRCUMFERENCE = "android.permission.health.WRITE_WAIST_CIRCUMFERENCE"
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/IntermenstrualBleedingRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/IntermenstrualBleedingRecord.kt
new file mode 100644
index 0000000..9de56a8
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/IntermenstrualBleedingRecord.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 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.records.metadata.Metadata
+import java.time.Instant
+import java.time.ZoneOffset
+
+/** Captures an instance of user's intermenstrual bleeding, also known as spotting. */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+class IntermenstrualBleedingRecord(
+ 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 (javaClass != other?.javaClass) return false
+
+ other as IntermenstrualBleedingRecord
+
+ 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 = time.hashCode()
+ result = 31 * result + (zoneOffset?.hashCode() ?: 0)
+ result = 31 * result + metadata.hashCode()
+ return result
+ }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/MenstruationFlowRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/MenstruationFlowRecord.kt
index c7d2aa5..045e955 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/MenstruationFlowRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/MenstruationFlowRecord.kt
@@ -15,25 +15,21 @@
*/
package androidx.health.connect.client.records
+import androidx.annotation.IntDef
import androidx.annotation.RestrictTo
-import androidx.annotation.StringDef
import androidx.health.connect.client.records.metadata.Metadata
import java.time.Instant
import java.time.ZoneOffset
/**
- * Captures a description of how heavy a user's menstrual flow was (spotting, light, medium, or
+ * Captures a description of how heavy a user's menstrual flow was (light, medium, or
* heavy). Each record represents a description of how heavy the user's menstrual bleeding was.
*/
public class MenstruationFlowRecord(
override val time: Instant,
override val zoneOffset: ZoneOffset?,
- /**
- * How heavy the user's menstrual flow was. Optional field. Allowed values: [Flow].
- *
- * @see Flow
- */
- @property:Flows public val flow: String? = null,
+ /** How heavy the user's menstrual flow was. Optional field. */
+ @property:Flows public val flow: Int = FLOW_UNKNOWN,
override val metadata: Metadata = Metadata.EMPTY,
) : InstantaneousRecord {
override fun equals(other: Any?): Boolean {
@@ -49,36 +45,35 @@
}
override fun hashCode(): Int {
- var result = 0
- result = 31 * result + flow.hashCode()
+ var result = flow
result = 31 * result + time.hashCode()
result = 31 * result + (zoneOffset?.hashCode() ?: 0)
result = 31 * result + metadata.hashCode()
return result
}
- /** How heavy the user's menstruation flow was. */
- public object Flow {
- const val SPOTTING = "spotting"
- const val LIGHT = "light"
- const val MEDIUM = "medium"
- const val HEAVY = "heavy"
- }
+ companion object {
+ const val FLOW_UNKNOWN = 0
+ const val FLOW_LIGHT = 1
+ const val FLOW_MEDIUM = 2
+ const val FLOW_HEAVY = 3
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
+ @JvmField
+ val FLOW_TYPE_STRING_TO_INT_MAP: Map<String, Int> =
+ mapOf("light" to FLOW_LIGHT, "medium" to FLOW_MEDIUM, "heavy" to FLOW_HEAVY)
+
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
+ @JvmField
+ val FLOW_TYPE_INT_TO_STRING_MAP: Map<Int, String> =
+ FLOW_TYPE_STRING_TO_INT_MAP.entries.associateBy({ it.value }, { it.key })
+ }
/**
* How heavy the user's menstruation flow was.
* @suppress
*/
@Retention(AnnotationRetention.SOURCE)
- @StringDef(
- value =
- [
- MenstruationFlowRecord.Flow.SPOTTING,
- MenstruationFlowRecord.Flow.LIGHT,
- MenstruationFlowRecord.Flow.MEDIUM,
- MenstruationFlowRecord.Flow.HEAVY,
- ]
- )
+ @IntDef(value = [FLOW_UNKNOWN, FLOW_LIGHT, FLOW_MEDIUM, FLOW_HEAVY])
@RestrictTo(RestrictTo.Scope.LIBRARY)
annotation class Flows
}
diff --git a/health/connect/connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt b/health/connect/connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt
index bcd4c96..0291436 100644
--- a/health/connect/connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt
+++ b/health/connect/connect-client/src/test/java/androidx/health/connect/client/impl/converters/records/AllRecordsConverterTest.kt
@@ -50,10 +50,10 @@
import androidx.health.connect.client.records.HeightRecord
import androidx.health.connect.client.records.HipCircumferenceRecord
import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.IntermenstrualBleedingRecord
import androidx.health.connect.client.records.LeanBodyMassRecord
import androidx.health.connect.client.records.MealType
import androidx.health.connect.client.records.MenstruationFlowRecord
-import androidx.health.connect.client.records.MenstruationFlowRecord.Flow
import androidx.health.connect.client.records.NutritionRecord
import androidx.health.connect.client.records.OvulationTestRecord
import androidx.health.connect.client.records.OxygenSaturationRecord
@@ -468,6 +468,19 @@
}
@Test
+ fun testIntermenstrualBleeding() {
+ val data =
+ IntermenstrualBleedingRecord(
+ time = START_TIME,
+ zoneOffset = END_ZONE_OFFSET,
+ metadata = TEST_METADATA
+ )
+
+ checkProtoAndRecordTypeNameMatch(data)
+ assertThat(toRecord(data.toProto())).isEqualTo(data)
+ }
+
+ @Test
fun testLeanBodyMass() {
val data =
LeanBodyMassRecord(
@@ -485,7 +498,7 @@
fun testMenstruation() {
val data =
MenstruationFlowRecord(
- flow = Flow.HEAVY,
+ flow = MenstruationFlowRecord.FLOW_HEAVY,
time = START_TIME,
zoneOffset = END_ZONE_OFFSET,
metadata = TEST_METADATA