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.units 17 18 import android.os.Bundle 19 import androidx.annotation.StringRes 20 import androidx.preference.ListPreference 21 import com.android.healthconnect.controller.R 22 import com.android.healthconnect.controller.dataentries.units.DistanceUnit.* 23 import com.android.healthconnect.controller.dataentries.units.EnergyUnit.* 24 import com.android.healthconnect.controller.dataentries.units.HeightUnit.* 25 import com.android.healthconnect.controller.dataentries.units.TemperatureUnit.CELSIUS 26 import com.android.healthconnect.controller.dataentries.units.TemperatureUnit.FAHRENHEIT 27 import com.android.healthconnect.controller.dataentries.units.TemperatureUnit.KELVIN 28 import com.android.healthconnect.controller.dataentries.units.UnitPreferences.Companion.DISTANCE_UNIT_PREF_KEY 29 import com.android.healthconnect.controller.dataentries.units.UnitPreferences.Companion.ENERGY_UNIT_PREF_KEY 30 import com.android.healthconnect.controller.dataentries.units.UnitPreferences.Companion.HEIGHT_UNIT_PREF_KEY 31 import com.android.healthconnect.controller.dataentries.units.UnitPreferences.Companion.TEMPERATURE_UNIT_PREF_KEY 32 import com.android.healthconnect.controller.dataentries.units.UnitPreferences.Companion.WEIGHT_UNIT_PREF_KEY 33 import com.android.healthconnect.controller.dataentries.units.UnitPreferencesStrings.getUnitLabel 34 import com.android.healthconnect.controller.dataentries.units.WeightUnit.KILOGRAM 35 import com.android.healthconnect.controller.dataentries.units.WeightUnit.POUND 36 import com.android.healthconnect.controller.dataentries.units.WeightUnit.STONE 37 import com.android.healthconnect.controller.shared.preference.HealthPreferenceFragment 38 import com.android.healthconnect.controller.utils.logging.ElementName 39 import com.android.healthconnect.controller.utils.logging.HealthConnectLogger 40 import com.android.healthconnect.controller.utils.logging.PageName 41 import com.android.healthconnect.controller.utils.logging.UnitsElement 42 import dagger.hilt.android.AndroidEntryPoint 43 import javax.inject.Inject 44 45 @AndroidEntryPoint(HealthPreferenceFragment::class) 46 class UnitsFragment : Hilt_UnitsFragment() { 47 48 @Inject lateinit var logger: HealthConnectLogger 49 @Inject lateinit var unitsPreferences: UnitPreferences 50 init { 51 this.setPageName(PageName.UNITS_PAGE) 52 } 53 54 override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { 55 setPreferencesFromResource(R.xml.units_screen, rootKey) 56 57 val height = 58 createUnitPreference( 59 HEIGHT_UNIT_PREF_KEY, 60 UnitsElement.CHANGE_UNITS_HEIGHT_BUTTON, 61 R.string.height_unit_title, 62 unitsPreferences.getHeightUnit().toString()) { newUnit -> 63 val newHeightUnit = HeightUnit.valueOf(newUnit) 64 val logName = 65 when (newHeightUnit) { 66 CENTIMETERS -> UnitsElement.CENTIMETERS_BUTTON 67 FEET -> UnitsElement.FEET_AND_INCHES_BUTTON 68 } 69 logger.logInteraction(logName) 70 unitsPreferences.setHeightUnit(newHeightUnit) 71 } 72 val weight = 73 createUnitPreference( 74 WEIGHT_UNIT_PREF_KEY, 75 UnitsElement.CHANGE_UNITS_WEIGHT_BUTTON, 76 R.string.weight_unit_title, 77 unitsPreferences.getWeightUnit().toString()) { newUnit -> 78 val newWeightUnit = WeightUnit.valueOf(newUnit) 79 val logName = 80 when (newWeightUnit) { 81 POUND -> UnitsElement.POUNDS_BUTTON 82 KILOGRAM -> UnitsElement.KILOGRAMS_BUTTON 83 STONE -> UnitsElement.STONES_BUTTON 84 } 85 logger.logInteraction(logName) 86 unitsPreferences.setWeightUnit(newWeightUnit) 87 } 88 val distance = 89 createUnitPreference( 90 DISTANCE_UNIT_PREF_KEY, 91 UnitsElement.CHANGE_UNITS_DISTANCE_BUTTON, 92 R.string.distance_unit_title, 93 unitsPreferences.getDistanceUnit().toString()) { newUnit -> 94 val newDistanceUnit = DistanceUnit.valueOf(newUnit) 95 val logName = 96 when (newDistanceUnit) { 97 KILOMETERS -> UnitsElement.KILOMETERS_BUTTON 98 MILES -> UnitsElement.MILES_BUTTON 99 } 100 logger.logInteraction(logName) 101 unitsPreferences.setDistanceUnit(newDistanceUnit) 102 } 103 val energy = 104 createUnitPreference( 105 ENERGY_UNIT_PREF_KEY, 106 UnitsElement.CHANGE_UNITS_ENERGY_BUTTON, 107 R.string.energy_unit_title, 108 unitsPreferences.getEnergyUnit().toString()) { newUnit -> 109 val newEnergyUnit = EnergyUnit.valueOf(newUnit) 110 val logName = 111 when (newEnergyUnit) { 112 CALORIE -> UnitsElement.CALORIES_BUTTON 113 KILOJOULE -> UnitsElement.KILOJOULES_BUTTON 114 } 115 logger.logInteraction(logName) 116 unitsPreferences.setEnergyUnit(newEnergyUnit) 117 } 118 val temperature = 119 createUnitPreference( 120 TEMPERATURE_UNIT_PREF_KEY, 121 UnitsElement.CHANGE_UNITS_TEMPERATURE_BUTTON, 122 R.string.temperature_unit_title, 123 unitsPreferences.getTemperatureUnit().toString()) { newUnit -> 124 val newTemperatureUnit = TemperatureUnit.valueOf(newUnit) 125 val logName = 126 when (newTemperatureUnit) { 127 CELSIUS -> UnitsElement.CELSIUS_BUTTON 128 FAHRENHEIT -> UnitsElement.FAHRENHEIT_BUTTON 129 KELVIN -> UnitsElement.KELVIN_BUTTON 130 } 131 logger.logInteraction(logName) 132 unitsPreferences.setTemperatureUnit(newTemperatureUnit) 133 } 134 preferenceScreen.addPreference(height) 135 preferenceScreen.addPreference(weight) 136 preferenceScreen.addPreference(distance) 137 preferenceScreen.addPreference(energy) 138 preferenceScreen.addPreference(temperature) 139 } 140 141 private fun createUnitPreference( 142 key: String, 143 logName: ElementName, 144 @StringRes title: Int, 145 unitValue: String, 146 onNewValue: (String) -> Unit 147 ): ListPreference { 148 val listPreference = ListPreference(requireContext()) 149 logger.logImpression(logName) 150 151 with(listPreference) { 152 isPersistent = false 153 isIconSpaceReserved = false 154 value = unitValue 155 setKey(key) 156 setTitle(title) 157 setDialogTitle(title) 158 setEntries(getEntries(key)) 159 setEntryValues(getEntriesValues(key)) 160 setSummary("%s") 161 setNegativeButtonText(R.string.units_cancel) 162 } 163 listPreference.setOnPreferenceChangeListener { _, newValue -> 164 onNewValue(newValue.toString()) 165 true 166 } 167 168 return listPreference 169 } 170 171 private fun getEntries(key: String): Array<String> { 172 val entries = getUnits(key) 173 return entries.map { getString(getUnitLabel(it)) }.toTypedArray() 174 } 175 176 private fun getEntriesValues(key: String): Array<String> { 177 val entries = getUnits(key) 178 return entries.map { it.toString() }.toTypedArray() 179 } 180 181 private fun getUnits(key: String): Array<UnitPreference> { 182 return when (key) { 183 DISTANCE_UNIT_PREF_KEY -> arrayOf(KILOMETERS, MILES) 184 HEIGHT_UNIT_PREF_KEY -> arrayOf(CENTIMETERS, FEET) 185 WEIGHT_UNIT_PREF_KEY -> arrayOf(POUND, KILOGRAM, STONE) 186 ENERGY_UNIT_PREF_KEY -> arrayOf(CALORIE, KILOJOULE) 187 TEMPERATURE_UNIT_PREF_KEY -> arrayOf(CELSIUS, FAHRENHEIT, KELVIN) 188 else -> emptyArray() 189 } 190 } 191 } 192