1 /**
<lambda>null2  * 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.PowerRecord
20 import android.health.connect.datatypes.PowerRecord.PowerRecordSample
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.data.entries.FormattedEntry.FormattedSessionDetail
26 import com.android.healthconnect.controller.dataentries.formatters.shared.EntryFormatter
27 import com.android.healthconnect.controller.dataentries.formatters.shared.RecordDetailsFormatter
28 import com.android.healthconnect.controller.dataentries.units.UnitPreferences
29 import com.android.healthconnect.controller.utils.LocalDateTimeFormatter
30 import dagger.hilt.android.qualifiers.ApplicationContext
31 import javax.inject.Inject
32 import javax.inject.Singleton
33 
34 /** Formatter for printing Power series data. */
35 @Singleton
36 class PowerFormatter @Inject constructor(@ApplicationContext private val context: Context) :
37     EntryFormatter<PowerRecord>(context), RecordDetailsFormatter<PowerRecord> {
38 
39     private val timeFormatter = LocalDateTimeFormatter(context)
40 
41     override suspend fun formatRecord(
42         record: PowerRecord,
43         header: String,
44         headerA11y: String,
45         unitPreferences: UnitPreferences
46     ): FormattedEntry {
47         return FormattedEntry.SeriesDataEntry(
48             uuid = record.metadata.id,
49             header = header,
50             headerA11y = headerA11y,
51             title = formatValue(record, unitPreferences),
52             titleA11y = formatA11yValue(record, unitPreferences),
53             dataType = getDataType(record))
54     }
55 
56     override suspend fun formatValue(
57         record: PowerRecord,
58         unitPreferences: UnitPreferences
59     ): String {
60         return format(R.string.watt_format, record.samples)
61     }
62 
63     override suspend fun formatA11yValue(
64         record: PowerRecord,
65         unitPreferences: UnitPreferences
66     ): String {
67         return format(R.string.watt_format_long, record.samples)
68     }
69 
70     override suspend fun formatRecordDetails(record: PowerRecord): List<FormattedEntry> {
71         return record.samples
72             .sortedBy { it.time }
73             .map { sample -> formatSample(record.metadata.id, sample) }
74     }
75 
76     private fun format(@StringRes res: Int, samples: List<PowerRecordSample>): String {
77         if (samples.isEmpty()) {
78             return context.getString(R.string.no_data)
79         }
80         val avrPower = samples.sumOf { it.power.inWatts } / samples.size
81         return MessageFormat.format(context.getString(res), mapOf("value" to avrPower))
82     }
83 
84     private fun formatSample(id: String, sample: PowerRecordSample): FormattedSessionDetail {
85         return FormattedSessionDetail(
86             uuid = id,
87             header = timeFormatter.formatTime(sample.time),
88             headerA11y = timeFormatter.formatTime(sample.time),
89             title =
90                 MessageFormat.format(
91                     context.getString(R.string.watt_format),
92                     mapOf("value" to sample.power.inWatts)),
93             titleA11y =
94                 MessageFormat.format(
95                     context.getString(R.string.watt_format_long),
96                     mapOf("value" to sample.power.inWatts)),
97         )
98     }
99 }
100