• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
<lambda>null2  * Copyright (C) 2024 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.controller.dataentries.formatters
17 
18 import android.content.Context
19 import android.health.connect.datatypes.ExerciseCompletionGoal
20 import android.health.connect.datatypes.PlannedExerciseStep
21 import com.android.healthconnect.controller.R
22 import com.android.healthconnect.controller.data.entries.FormattedEntry
23 import com.android.healthconnect.controller.data.entries.FormattedEntry.FormattedSectionContent
24 import com.android.healthconnect.controller.data.entries.FormattedEntry.PlannedExerciseStepEntry
25 import com.android.healthconnect.controller.dataentries.formatters.shared.LengthFormatter
26 import com.android.healthconnect.controller.dataentries.units.UnitPreferences
27 import dagger.hilt.android.qualifiers.ApplicationContext
28 import javax.inject.Inject
29 
30 /** Formatter for printing PlannedExerciseStep data. */
31 class PlannedExerciseStepFormatter
32 @Inject
33 constructor(
34     @ApplicationContext private val context: Context,
35     private val exercisePerformanceGoalFormatter: ExercisePerformanceGoalFormatter,
36     private val exerciseSegmentTypeFormatter: ExerciseSegmentTypeFormatter
37 ) {
38 
39     fun formatStep(step: PlannedExerciseStep, unitPreferences: UnitPreferences): FormattedEntry {
40         return PlannedExerciseStepEntry(
41             step = step,
42             title = formatStepTitle(step, unitPreferences),
43             titleA11y = formatStepTitleA11y(step, unitPreferences))
44     }
45 
46     fun formatStepDetails(
47         step: PlannedExerciseStep,
48         unitPreferences: UnitPreferences
49     ): List<FormattedEntry> {
50         val performanceGoals = step.performanceGoals
51         return buildList {
52             if (!step.description.isNullOrBlank()) {
53                 add(FormattedSectionContent(title = step.description.toString(), bulleted = true))
54             }
55 
56             if (performanceGoals.isNotEmpty()) {
57                 performanceGoals.forEach { performanceGoal ->
58                     add(
59                         exercisePerformanceGoalFormatter.formatGoal(
60                             performanceGoal, unitPreferences, step.exerciseType))
61                 }
62             }
63         }
64     }
65 
66     private fun formatStepTitle(
67         step: PlannedExerciseStep,
68         unitPreferences: UnitPreferences
69     ): String {
70         val completionGoal = step.completionGoal
71         val exerciseSegmentType = step.exerciseType
72         return context.getString(
73             R.string.planned_exercise_step_title,
74             formatCompletionGoal(completionGoal, unitPreferences),
75             exerciseSegmentTypeFormatter.getSegmentType(exerciseSegmentType))
76     }
77 
78     private fun formatStepTitleA11y(
79         step: PlannedExerciseStep,
80         unitPreferences: UnitPreferences
81     ): String {
82         val completionGoal = step.completionGoal
83         val exerciseSegmentType = step.exerciseType
84         return context.getString(
85             R.string.planned_exercise_step_title,
86             formatCompletionGoalA11y(completionGoal, unitPreferences),
87             exerciseSegmentTypeFormatter.getSegmentType(exerciseSegmentType))
88     }
89 
90     private fun formatCompletionGoal(
91         completionGoal: ExerciseCompletionGoal,
92         unitPreferences: UnitPreferences
93     ): String {
94         return when (completionGoal) {
95             is ExerciseCompletionGoal.DistanceGoal ->
96                 LengthFormatter.formatValue(context, completionGoal.distance, unitPreferences)
97             is ExerciseCompletionGoal.DurationGoal ->
98                 DurationFormatter.formatDurationShort(context, completionGoal.duration)
99             is ExerciseCompletionGoal.StepsGoal ->
100                 StepsFormatter(context).formatUnit(completionGoal.steps.toLong())
101             is ExerciseCompletionGoal.RepetitionsGoal -> completionGoal.repetitions.toString()
102             is ExerciseCompletionGoal.ActiveCaloriesBurnedGoal ->
103                 context.getString(
104                     R.string.active_calories_burned,
105                     EnergyFormatter.formatEnergyValue(
106                         context, completionGoal.activeCalories, unitPreferences))
107             is ExerciseCompletionGoal.DistanceWithVariableRestGoal ->
108                 context.getString(
109                     R.string.distance_with_variable_rest_goal_formatted,
110                     LengthFormatter.formatValue(context, completionGoal.distance, unitPreferences),
111                     DurationFormatter.formatDurationShort(context, completionGoal.duration))
112             is ExerciseCompletionGoal.TotalCaloriesBurnedGoal ->
113                 context.getString(
114                     R.string.total_calories_burned,
115                     EnergyFormatter.formatEnergyValue(
116                         context, completionGoal.totalCalories, unitPreferences))
117             else -> throw IllegalArgumentException("Unknown completion goal $completionGoal")
118         }
119     }
120 
121     private fun formatCompletionGoalA11y(
122         completionGoal: ExerciseCompletionGoal,
123         unitPreferences: UnitPreferences
124     ): String {
125         return when (completionGoal) {
126             is ExerciseCompletionGoal.DistanceGoal ->
127                 LengthFormatter.formatA11yValue(context, completionGoal.distance, unitPreferences)
128             is ExerciseCompletionGoal.DurationGoal ->
129                 DurationFormatter.formatDurationLong(context, completionGoal.duration)
130             is ExerciseCompletionGoal.StepsGoal ->
131                 StepsFormatter(context).formatA11yUnit(completionGoal.steps.toLong())
132             is ExerciseCompletionGoal.RepetitionsGoal -> completionGoal.repetitions.toString()
133             is ExerciseCompletionGoal.ActiveCaloriesBurnedGoal ->
134                 context.getString(
135                     R.string.active_calories_burned,
136                     EnergyFormatter.formatEnergyA11yValue(
137                         context, completionGoal.activeCalories, unitPreferences))
138             is ExerciseCompletionGoal.DistanceWithVariableRestGoal ->
139                 context.getString(
140                     R.string.distance_with_variable_rest_goal_formatted,
141                     LengthFormatter.formatA11yValue(
142                         context, completionGoal.distance, unitPreferences),
143                     DurationFormatter.formatDurationLong(context, completionGoal.duration))
144             is ExerciseCompletionGoal.TotalCaloriesBurnedGoal ->
145                 context.getString(
146                     R.string.total_calories_burned,
147                     EnergyFormatter.formatEnergyA11yValue(
148                         context, completionGoal.totalCalories, unitPreferences))
149             else -> throw IllegalArgumentException("Unknown completion goal $completionGoal")
150         }
151     }
152 }
153