1 /**
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * ```
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  * ```
10  *
11  * Unless required by applicable law or agreed to in writing, software distributed under the License
12  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13  * or implied. See the License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.android.healthconnect.testapps.toolbox
17 
18 import android.health.connect.datatypes.ActiveCaloriesBurnedRecord
19 import android.health.connect.datatypes.BasalBodyTemperatureRecord
20 import android.health.connect.datatypes.BasalMetabolicRateRecord
21 import android.health.connect.datatypes.BloodGlucoseRecord
22 import android.health.connect.datatypes.BloodPressureRecord
23 import android.health.connect.datatypes.BodyFatRecord
24 import android.health.connect.datatypes.BodyTemperatureRecord
25 import android.health.connect.datatypes.BodyWaterMassRecord
26 import android.health.connect.datatypes.BoneMassRecord
27 import android.health.connect.datatypes.CervicalMucusRecord
28 import android.health.connect.datatypes.CyclingPedalingCadenceRecord
29 import android.health.connect.datatypes.DistanceRecord
30 import android.health.connect.datatypes.ElevationGainedRecord
31 import android.health.connect.datatypes.ExerciseSessionRecord
32 import android.health.connect.datatypes.FloorsClimbedRecord
33 import android.health.connect.datatypes.HeartRateRecord
34 import android.health.connect.datatypes.HeartRateVariabilityRmssdRecord
35 import android.health.connect.datatypes.HeightRecord
36 import android.health.connect.datatypes.HydrationRecord
37 import android.health.connect.datatypes.IntermenstrualBleedingRecord
38 import android.health.connect.datatypes.LeanBodyMassRecord
39 import android.health.connect.datatypes.MenstruationFlowRecord
40 import android.health.connect.datatypes.MenstruationPeriodRecord
41 import android.health.connect.datatypes.NutritionRecord
42 import android.health.connect.datatypes.OvulationTestRecord
43 import android.health.connect.datatypes.OxygenSaturationRecord
44 import android.health.connect.datatypes.PlannedExerciseSessionRecord
45 import android.health.connect.datatypes.PowerRecord
46 import android.health.connect.datatypes.Record
47 import android.health.connect.datatypes.RespiratoryRateRecord
48 import android.health.connect.datatypes.RestingHeartRateRecord
49 import android.health.connect.datatypes.SexualActivityRecord
50 import android.health.connect.datatypes.SkinTemperatureRecord
51 import android.health.connect.datatypes.SleepSessionRecord
52 import android.health.connect.datatypes.SpeedRecord
53 import android.health.connect.datatypes.StepsCadenceRecord
54 import android.health.connect.datatypes.StepsRecord
55 import android.health.connect.datatypes.TotalCaloriesBurnedRecord
56 import android.health.connect.datatypes.Vo2MaxRecord
57 import android.health.connect.datatypes.WeightRecord
58 import android.health.connect.datatypes.WheelchairPushesRecord
59 import android.text.InputType
60 import androidx.annotation.DrawableRes
61 import androidx.annotation.StringRes
62 import kotlin.reflect.KClass
63 
64 /** Constant variables used across the app. */
65 object Constants {
66 
67     const val INPUT_TYPE_DOUBLE = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
68     const val INPUT_TYPE_SIGNED_DOUBLE =
69         InputType.TYPE_CLASS_NUMBER or
70             InputType.TYPE_NUMBER_FLAG_DECIMAL or
71             InputType.TYPE_NUMBER_FLAG_SIGNED
72     const val INPUT_TYPE_LONG = InputType.TYPE_CLASS_NUMBER
73     const val INPUT_TYPE_INT = InputType.TYPE_CLASS_NUMBER
74     const val INPUT_TYPE_TEXT = InputType.TYPE_CLASS_TEXT
75 
76     val DATA_TYPE_PERMISSIONS =
77         arrayOf(
78             "android.permission.health.READ_ACTIVE_CALORIES_BURNED",
79             "android.permission.health.READ_BASAL_BODY_TEMPERATURE",
80             "android.permission.health.READ_BASAL_METABOLIC_RATE",
81             "android.permission.health.READ_BLOOD_GLUCOSE",
82             "android.permission.health.READ_BLOOD_PRESSURE",
83             "android.permission.health.READ_BODY_FAT",
84             "android.permission.health.READ_BODY_TEMPERATURE",
85             "android.permission.health.READ_BODY_WATER_MASS",
86             "android.permission.health.READ_BONE_MASS",
87             "android.permission.health.READ_CERVICAL_MUCUS",
88             "android.permission.health.READ_DISTANCE",
89             "android.permission.health.READ_ELEVATION_GAINED",
90             "android.permission.health.READ_EXERCISE",
91             "android.permission.health.READ_PLANNED_EXERCISE",
92             "android.permission.health.READ_EXERCISE_ROUTES",
93             "android.permission.health.READ_FLOORS_CLIMBED",
94             "android.permission.health.READ_HEART_RATE",
95             "android.permission.health.READ_HEART_RATE_VARIABILITY",
96             "android.permission.health.READ_HEIGHT",
97             "android.permission.health.READ_HYDRATION",
98             "android.permission.health.READ_LEAN_BODY_MASS",
99             "android.permission.health.READ_MENSTRUATION",
100             "android.permission.health.READ_NUTRITION",
101             "android.permission.health.READ_OVULATION_TEST",
102             "android.permission.health.READ_OXYGEN_SATURATION",
103             "android.permission.health.READ_POWER",
104             "android.permission.health.READ_RESPIRATORY_RATE",
105             "android.permission.health.READ_RESTING_HEART_RATE",
106             "android.permission.health.READ_SEXUAL_ACTIVITY",
107             "android.permission.health.READ_SKIN_TEMPERATURE",
108             "android.permission.health.READ_SLEEP",
109             "android.permission.health.READ_SPEED",
110             "android.permission.health.READ_STEPS",
111             "android.permission.health.READ_TOTAL_CALORIES_BURNED",
112             "android.permission.health.READ_VO2_MAX",
113             "android.permission.health.READ_WEIGHT",
114             "android.permission.health.READ_INTERMENSTRUAL_BLEEDING",
115             "android.permission.health.READ_WHEELCHAIR_PUSHES",
116             "android.permission.health.WRITE_ACTIVE_CALORIES_BURNED",
117             "android.permission.health.WRITE_BASAL_BODY_TEMPERATURE",
118             "android.permission.health.WRITE_BASAL_METABOLIC_RATE",
119             "android.permission.health.WRITE_BLOOD_GLUCOSE",
120             "android.permission.health.WRITE_BLOOD_PRESSURE",
121             "android.permission.health.WRITE_BODY_FAT",
122             "android.permission.health.WRITE_BODY_TEMPERATURE",
123             "android.permission.health.WRITE_BODY_WATER_MASS",
124             "android.permission.health.WRITE_BONE_MASS",
125             "android.permission.health.WRITE_CERVICAL_MUCUS",
126             "android.permission.health.WRITE_DISTANCE",
127             "android.permission.health.WRITE_ELEVATION_GAINED",
128             "android.permission.health.WRITE_EXERCISE",
129             "android.permission.health.WRITE_PLANNED_EXERCISE",
130             "android.permission.health.WRITE_FLOORS_CLIMBED",
131             "android.permission.health.WRITE_HEART_RATE",
132             "android.permission.health.WRITE_HEART_RATE_VARIABILITY",
133             "android.permission.health.WRITE_HEIGHT",
134             "android.permission.health.WRITE_HYDRATION",
135             "android.permission.health.WRITE_LEAN_BODY_MASS",
136             "android.permission.health.WRITE_MENSTRUATION",
137             "android.permission.health.WRITE_NUTRITION",
138             "android.permission.health.WRITE_OVULATION_TEST",
139             "android.permission.health.WRITE_OXYGEN_SATURATION",
140             "android.permission.health.WRITE_POWER",
141             "android.permission.health.WRITE_RESPIRATORY_RATE",
142             "android.permission.health.WRITE_RESTING_HEART_RATE",
143             "android.permission.health.WRITE_SEXUAL_ACTIVITY",
144             "android.permission.health.WRITE_SKIN_TEMPERATURE",
145             "android.permission.health.WRITE_SLEEP",
146             "android.permission.health.WRITE_SPEED",
147             "android.permission.health.WRITE_STEPS",
148             "android.permission.health.WRITE_TOTAL_CALORIES_BURNED",
149             "android.permission.health.WRITE_VO2_MAX",
150             "android.permission.health.WRITE_WEIGHT",
151             "android.permission.health.WRITE_WHEELCHAIR_PUSHES",
152             "android.permission.health.WRITE_INTERMENSTRUAL_BLEEDING",
153             "android.permission.health.WRITE_EXERCISE_ROUTE")
154 
155     const val READ_HEALTH_DATA_IN_BACKGROUND =
156         "android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND"
157     const val READ_HEALTH_DATA_HISTORY = "android.permission.health.READ_HEALTH_DATA_HISTORY"
158 
159     val ADDITIONAL_PERMISSIONS = arrayOf(READ_HEALTH_DATA_IN_BACKGROUND, READ_HEALTH_DATA_HISTORY)
160 
161     const val READ_IMMUNIZATION = "android.permission.health.READ_MEDICAL_DATA_IMMUNIZATION"
162     const val WRITE_ALL_MEDICAL_DATA = "android.permission.health.WRITE_MEDICAL_DATA"
163     val MEDICAL_PERMISSIONS =
164         arrayOf(
165             WRITE_ALL_MEDICAL_DATA,
166             READ_IMMUNIZATION,
167         )
168 
169     val HEALTH_PERMISSIONS = DATA_TYPE_PERMISSIONS + ADDITIONAL_PERMISSIONS + MEDICAL_PERMISSIONS
170 
171     /** Represents Category group for HealthConnect data. */
172     enum class HealthDataCategory(
173         val healthPermissionTypes: List<HealthPermissionType>,
174         @StringRes val title: Int,
175         @DrawableRes val icon: Int,
176     ) {
177         ACTIVITY(
178             CategoriesMappers.ACTIVITY_PERMISSION_GROUPS,
179             R.string.activity_category,
180             R.drawable.quantum_gm_ic_directions_run_vd_theme_24),
181         BODY_MEASUREMENTS(
182             CategoriesMappers.BODY_MEASUREMENTS_PERMISSION_GROUPS,
183             R.string.body_measurements_category,
184             R.drawable.quantum_gm_ic_straighten_vd_theme_24),
185         SLEEP(
186             CategoriesMappers.SLEEP_PERMISSION_GROUPS,
187             R.string.sleep_category,
188             R.drawable.ic_sleep),
189         VITALS(
190             CategoriesMappers.VITALS_PERMISSION_GROUPS,
191             R.string.vitals_category,
192             R.drawable.ic_vitals),
193         CYCLE_TRACKING(
194             CategoriesMappers.CYCLE_TRACKING_PERMISSION_GROUPS,
195             R.string.cycle_tracking_category,
196             R.drawable.ic_cycle_tracking),
197         NUTRITION(
198             CategoriesMappers.NUTRITION_PERMISSION_GROUPS,
199             R.string.nutrition_category,
200             R.drawable.quantum_gm_ic_grocery_vd_theme_24),
201     }
202 
203     /** Permission groups for each {@link HealthDataCategory}. */
204     object CategoriesMappers {
205         val ACTIVITY_PERMISSION_GROUPS =
206             listOf(
207                 HealthPermissionType.PLANNED_EXERCISE,
208                 HealthPermissionType.ACTIVE_CALORIES_BURNED,
209                 HealthPermissionType.DISTANCE,
210                 HealthPermissionType.ELEVATION_GAINED,
211                 HealthPermissionType.FLOORS_CLIMBED,
212                 HealthPermissionType.POWER,
213                 HealthPermissionType.SPEED,
214                 HealthPermissionType.STEPS,
215                 HealthPermissionType.STEPS_CADENCE,
216                 HealthPermissionType.TOTAL_CALORIES_BURNED,
217                 HealthPermissionType.VO2_MAX,
218                 HealthPermissionType.CYCLING_PEDALING_CADENCE,
219                 HealthPermissionType.WHEELCHAIR_PUSHES,
220                 HealthPermissionType.EXERCISE_SESSION)
221 
222         val BODY_MEASUREMENTS_PERMISSION_GROUPS =
223             listOf(
224                 HealthPermissionType.BASAL_METABOLIC_RATE,
225                 HealthPermissionType.BODY_FAT,
226                 HealthPermissionType.BODY_WATER_MASS,
227                 HealthPermissionType.BONE_MASS,
228                 HealthPermissionType.HEIGHT,
229                 HealthPermissionType.LEAN_BODY_MASS,
230                 HealthPermissionType.WEIGHT)
231 
232         val CYCLE_TRACKING_PERMISSION_GROUPS =
233             listOf(
234                 HealthPermissionType.CERVICAL_MUCUS,
235                 HealthPermissionType.MENSTRUATION_FLOW,
236                 HealthPermissionType.MENSTRUATION_PERIOD,
237                 HealthPermissionType.OVULATION_TEST,
238                 HealthPermissionType.INTERMENSTRUAL_BLEEDING,
239                 HealthPermissionType.SEXUAL_ACTIVITY)
240 
241         val NUTRITION_PERMISSION_GROUPS =
242             listOf(HealthPermissionType.HYDRATION, HealthPermissionType.NUTRITION)
243 
244         val SLEEP_PERMISSION_GROUPS = listOf(HealthPermissionType.SLEEP)
245 
246         val VITALS_PERMISSION_GROUPS =
247             listOf(
248                 HealthPermissionType.BASAL_BODY_TEMPERATURE,
249                 HealthPermissionType.BLOOD_GLUCOSE,
250                 HealthPermissionType.BLOOD_PRESSURE,
251                 HealthPermissionType.BODY_TEMPERATURE,
252                 HealthPermissionType.HEART_RATE,
253                 HealthPermissionType.HEART_RATE_VARIABILITY,
254                 HealthPermissionType.OXYGEN_SATURATION,
255                 HealthPermissionType.RESPIRATORY_RATE,
256                 HealthPermissionType.RESTING_HEART_RATE,
257                 HealthPermissionType.SKIN_TEMPERATURE)
258     }
259 
260     enum class HealthPermissionType(
261         val recordClass: KClass<out Record>?,
262         @StringRes val title: Int,
263     ) {
264         // ACTIVITY
265         ACTIVE_CALORIES_BURNED(
266             ActiveCaloriesBurnedRecord::class, R.string.active_calories_burned_label),
267         DISTANCE(DistanceRecord::class, R.string.distance_label),
268         ELEVATION_GAINED(ElevationGainedRecord::class, R.string.elevation_gained_label),
269         FLOORS_CLIMBED(FloorsClimbedRecord::class, R.string.floors_climbed_label),
270         STEPS(StepsRecord::class, R.string.steps_label),
271         STEPS_CADENCE(StepsCadenceRecord::class, R.string.steps_cadence_label),
272         TOTAL_CALORIES_BURNED(
273             TotalCaloriesBurnedRecord::class, R.string.total_calories_burned_label),
274         VO2_MAX(Vo2MaxRecord::class, R.string.vo2_max_label),
275         WHEELCHAIR_PUSHES(WheelchairPushesRecord::class, R.string.wheelchair_pushes_label),
276         POWER(PowerRecord::class, R.string.power_label),
277         SPEED(SpeedRecord::class, R.string.speed_label),
278         CYCLING_PEDALING_CADENCE(
279             CyclingPedalingCadenceRecord::class, R.string.cycling_pedaling_cadence),
280         EXERCISE_SESSION(ExerciseSessionRecord::class, R.string.exercise_session),
281         PLANNED_EXERCISE(PlannedExerciseSessionRecord::class, R.string.training_plans),
282 
283         // BODY_MEASUREMENTS
284         BASAL_METABOLIC_RATE(BasalMetabolicRateRecord::class, R.string.basal_metabolic_rate_label),
285         BODY_FAT(BodyFatRecord::class, R.string.body_fat_label),
286         BODY_WATER_MASS(BodyWaterMassRecord::class, R.string.body_water_mass_label),
287         BONE_MASS(BoneMassRecord::class, R.string.bone_mass_label),
288         HEIGHT(HeightRecord::class, R.string.height_label),
289         LEAN_BODY_MASS(LeanBodyMassRecord::class, R.string.lean_body_mass_label),
290         WEIGHT(WeightRecord::class, R.string.weight_label),
291 
292         // CYCLE_TRACKING
293         CERVICAL_MUCUS(CervicalMucusRecord::class, R.string.cervical_mucus_label),
294         MENSTRUATION_FLOW(MenstruationFlowRecord::class, R.string.menstruation_flow),
295         MENSTRUATION_PERIOD(MenstruationPeriodRecord::class, R.string.menstruation_period),
296         OVULATION_TEST(OvulationTestRecord::class, R.string.ovulation_test_label),
297         SEXUAL_ACTIVITY(SexualActivityRecord::class, R.string.sexual_activity_label),
298         INTERMENSTRUAL_BLEEDING(
299             IntermenstrualBleedingRecord::class, R.string.inter_menstrual_bleeding),
300 
301         // NUTRITION
302         HYDRATION(HydrationRecord::class, R.string.hydration_label),
303         NUTRITION(NutritionRecord::class, R.string.nutrition_label),
304 
305         // SLEEP
306         SLEEP(SleepSessionRecord::class, R.string.sleep_label),
307 
308         // VITALS
309         BASAL_BODY_TEMPERATURE(
310             BasalBodyTemperatureRecord::class, R.string.basal_body_temperature_label),
311         BLOOD_GLUCOSE(BloodGlucoseRecord::class, R.string.blood_glucose_label),
312         BLOOD_PRESSURE(BloodPressureRecord::class, R.string.blood_pressure_label),
313         BODY_TEMPERATURE(BodyTemperatureRecord::class, R.string.body_temperature_label),
314         HEART_RATE(HeartRateRecord::class, R.string.heart_rate_label),
315         HEART_RATE_VARIABILITY(
316             HeartRateVariabilityRmssdRecord::class, R.string.heart_rate_variability_label),
317         OXYGEN_SATURATION(OxygenSaturationRecord::class, R.string.oxygen_saturation_label),
318         RESPIRATORY_RATE(RespiratoryRateRecord::class, R.string.respiratory_rate_label),
319         RESTING_HEART_RATE(RestingHeartRateRecord::class, R.string.resting_heart_rate_label),
320         SKIN_TEMPERATURE(SkinTemperatureRecord::class, R.string.skin_temperature_label),
321     }
322 }
323