1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.carlauncher.calmmode; 18 19 import android.icu.number.Notation; 20 import android.icu.number.NumberFormatter; 21 import android.icu.number.Precision; 22 import android.icu.util.MeasureUnit; 23 import android.os.Build; 24 import android.util.Log; 25 26 import androidx.annotation.NonNull; 27 28 import java.util.Locale; 29 30 /** 31 * Class used to represent temperature 32 * <p>Contains a {@code float value} and {@link MeasureUnit unit} 33 * <p>Use {@link Builder} to create an instance of {@link TemperatureData} 34 */ 35 public class TemperatureData { 36 37 private static final String TAG = TemperatureData.class.getSimpleName(); 38 private static final boolean DEBUG = Build.isDebuggable(); 39 private float mValue; 40 @NonNull 41 private MeasureUnit mUnit; 42 TemperatureData(float value, @NonNull MeasureUnit unit)43 private TemperatureData(float value, @NonNull MeasureUnit unit) { 44 this.mValue = value; 45 this.mUnit = unit; 46 } 47 48 /** 49 * @param temperatureData temperature data 50 * @param locale locale to use for creating string 51 * @return compact string representation of the value based on the locale 52 */ 53 @NonNull buildTemperatureString( @onNull TemperatureData temperatureData, @NonNull Locale locale, boolean showUnit)54 public static String buildTemperatureString( 55 @NonNull TemperatureData temperatureData, @NonNull Locale locale, boolean showUnit) { 56 return NumberFormatter.withLocale(locale) 57 .notation(Notation.compactShort()) 58 .precision(Precision.integer()) 59 .unit(showUnit ? temperatureData.getUnit() : MeasureUnit.GENERIC_TEMPERATURE) 60 .format(temperatureData.getValue()) 61 .toString(); 62 } 63 64 /** 65 * Converts temperature value from Celsius to Fahrenheit 66 * 67 * @param temperatureInCelsius temperature value in Celsius 68 * @return temperature value in Fahrenheit 69 */ convertCelsiusToFahrenheit(float temperatureInCelsius)70 public static float convertCelsiusToFahrenheit(float temperatureInCelsius) { 71 return (temperatureInCelsius * 9f / 5f) + 32; 72 } 73 74 /** 75 * Converts temperature value from Fahrenheit to Celsius 76 * 77 * @param temperatureInFahrenheit temperature value in Fahrenheit 78 * @return temperature value in Celsius 79 */ convertFahrenheitToCelsius(float temperatureInFahrenheit)80 public static float convertFahrenheitToCelsius(float temperatureInFahrenheit) { 81 return (temperatureInFahrenheit - 32) * 5f / 9f; 82 } 83 getValue()84 public float getValue() { 85 return mValue; 86 } 87 88 @NonNull getUnit()89 public MeasureUnit getUnit() { 90 return mUnit; 91 } 92 93 @Override toString()94 public String toString() { 95 return "TemperatureData{" + "value=" + mValue + ", unit=" + mUnit + '}'; 96 } 97 98 99 /** Converts the value and changes unit from Fahrenheit to Celsius, 100 * does nothing if unit is already Celsius 101 */ convertToFahrenheit()102 public void convertToFahrenheit() { 103 if (mUnit == MeasureUnit.CELSIUS) { 104 mValue = convertCelsiusToFahrenheit(mValue); 105 mUnit = MeasureUnit.FAHRENHEIT; 106 return; 107 } 108 // no-op if unit is already FAHRENHEIT 109 if (DEBUG) { 110 Log.v(TAG, "Unit is already FAHRENHEIT. No conversion performed."); 111 } 112 } 113 114 /** Converts the value and changes unit to Fahrenheit, 115 * does nothing if unit is already Fahrenheit 116 */ convertToCelsius()117 public void convertToCelsius() { 118 if (mUnit == MeasureUnit.FAHRENHEIT) { 119 mValue = convertFahrenheitToCelsius(mValue); 120 mUnit = MeasureUnit.CELSIUS; 121 } 122 // no-op if unit is already CELSIUS 123 if (DEBUG) { 124 Log.v(TAG, "Unit is already CELSIUS. No conversion performed."); 125 } 126 } 127 128 public static final class Builder { 129 130 private float mValue; 131 @NonNull private MeasureUnit mUnit = MeasureUnit.CELSIUS; 132 Builder(float mValue, @NonNull MeasureUnit mUnit)133 private Builder(float mValue, @NonNull MeasureUnit mUnit) { 134 this.mValue = mValue; 135 this.mUnit = mUnit; 136 } 137 Builder()138 public Builder() {} 139 140 /** 141 * @param data TemperatureData object used to create Builder 142 * @return TemperatureData.Builder object 143 */ 144 @NonNull from(TemperatureData data)145 public static Builder from(TemperatureData data) { 146 return new Builder(data.getValue(), data.getUnit()); 147 } 148 149 /** 150 * @param temperatureCelsius temperature value in degrees Celsius 151 * @return {@link Builder builder} 152 */ setValueCelsius(float temperatureCelsius)153 Builder setValueCelsius(float temperatureCelsius) { 154 mValue = temperatureCelsius; 155 mUnit = MeasureUnit.CELSIUS; 156 return this; 157 } 158 setValueFahrenheit(float temperatureFahrenheit)159 Builder setValueFahrenheit(float temperatureFahrenheit) { 160 mValue = temperatureFahrenheit; 161 mUnit = MeasureUnit.FAHRENHEIT; 162 return this; 163 } 164 build()165 TemperatureData build() { 166 return new TemperatureData(mValue, mUnit); 167 } 168 } 169 } 170