• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.controller.dataentries.formatters
17 
18 import android.content.Context
19 import android.health.connect.datatypes.StepsCadenceRecord
20 import android.health.connect.datatypes.StepsCadenceRecord.StepsCadenceRecordSample
21 import android.icu.text.MessageFormat
22 import androidx.annotation.StringRes
23 import com.android.healthconnect.controller.R
24 import com.android.healthconnect.controller.data.entries.FormattedEntry
25 import com.android.healthconnect.controller.dataentries.formatters.shared.EntryFormatter
26 import com.android.healthconnect.controller.dataentries.formatters.shared.RecordDetailsFormatter
27 import com.android.healthconnect.controller.dataentries.units.UnitPreferences
28 import com.android.healthconnect.controller.utils.LocalDateTimeFormatter
29 import dagger.hilt.android.qualifiers.ApplicationContext
30 import javax.inject.Inject
31 
32 /** Formatter for printing StepsCadence series data. */
33 class StepsCadenceFormatter @Inject constructor(@ApplicationContext private val context: Context) :
34     EntryFormatter<StepsCadenceRecord>(context), RecordDetailsFormatter<StepsCadenceRecord> {
35 
36     private val timeFormatter = LocalDateTimeFormatter(context)
37 
formatRecordnull38     override suspend fun formatRecord(
39         record: StepsCadenceRecord,
40         header: String,
41         headerA11y: String,
42         unitPreferences: UnitPreferences,
43     ): FormattedEntry {
44         return FormattedEntry.SeriesDataEntry(
45             uuid = record.metadata.id,
46             header = header,
47             headerA11y = headerA11y,
48             title = formatValue(record, unitPreferences),
49             titleA11y = formatA11yValue(record, unitPreferences),
50             dataType = record::class,
51         )
52     }
53 
54     /** Returns localized average StepsCadence from multiple data points. */
formatValuenull55     override suspend fun formatValue(
56         record: StepsCadenceRecord,
57         unitPreferences: UnitPreferences,
58     ): String {
59         return formatRange(R.string.steps_per_minute, record.samples)
60     }
61 
62     /** Returns localized StepsCadence value. */
formatA11yValuenull63     override suspend fun formatA11yValue(
64         record: StepsCadenceRecord,
65         unitPreferences: UnitPreferences,
66     ): String {
67         return formatRange(R.string.steps_per_minute_long, record.samples)
68     }
69 
formatRecordDetailsnull70     override suspend fun formatRecordDetails(record: StepsCadenceRecord): List<FormattedEntry> {
71         return record.samples.sortedBy { it.time }.map { formatSample(record.metadata.id, it) }
72     }
73 
formatSamplenull74     private fun formatSample(
75         id: String,
76         sample: StepsCadenceRecordSample,
77     ): FormattedEntry.FormattedSessionDetail {
78         return FormattedEntry.FormattedSessionDetail(
79             uuid = id,
80             header = timeFormatter.formatTime(sample.time),
81             headerA11y = timeFormatter.formatTime(sample.time),
82             title =
83                 MessageFormat.format(
84                     context.getString(R.string.steps_per_minute),
85                     mapOf("value" to sample.rate),
86                 ),
87             titleA11y =
88                 MessageFormat.format(
89                     context.getString(R.string.steps_per_minute_long),
90                     mapOf("value" to sample.rate),
91                 ),
92         )
93     }
94 
formatRangenull95     private fun formatRange(@StringRes res: Int, samples: List<StepsCadenceRecordSample>): String {
96         return if (samples.isEmpty()) {
97             context.getString(R.string.no_data)
98         } else {
99             val avrStepsCadence = samples.sumOf { it.rate } / samples.size
100             MessageFormat.format(context.getString(res), mapOf("value" to avrStepsCadence))
101         }
102     }
103 }
104