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 android.health.connect.internal.datatypes.utils; 18 19 import static android.health.connect.datatypes.ActiveCaloriesBurnedRecord.ACTIVE_CALORIES_TOTAL; 20 import static android.health.connect.datatypes.ActivityIntensityRecord.DURATION_TOTAL; 21 import static android.health.connect.datatypes.ActivityIntensityRecord.INTENSITY_MINUTES_TOTAL; 22 import static android.health.connect.datatypes.ActivityIntensityRecord.MODERATE_DURATION_TOTAL; 23 import static android.health.connect.datatypes.ActivityIntensityRecord.VIGOROUS_DURATION_TOTAL; 24 import static android.health.connect.datatypes.BasalMetabolicRateRecord.BASAL_CALORIES_TOTAL; 25 import static android.health.connect.datatypes.BloodPressureRecord.DIASTOLIC_AVG; 26 import static android.health.connect.datatypes.BloodPressureRecord.DIASTOLIC_MAX; 27 import static android.health.connect.datatypes.BloodPressureRecord.DIASTOLIC_MIN; 28 import static android.health.connect.datatypes.BloodPressureRecord.SYSTOLIC_AVG; 29 import static android.health.connect.datatypes.BloodPressureRecord.SYSTOLIC_MAX; 30 import static android.health.connect.datatypes.BloodPressureRecord.SYSTOLIC_MIN; 31 import static android.health.connect.datatypes.CyclingPedalingCadenceRecord.RPM_AVG; 32 import static android.health.connect.datatypes.CyclingPedalingCadenceRecord.RPM_MAX; 33 import static android.health.connect.datatypes.CyclingPedalingCadenceRecord.RPM_MIN; 34 import static android.health.connect.datatypes.DistanceRecord.DISTANCE_TOTAL; 35 import static android.health.connect.datatypes.ElevationGainedRecord.ELEVATION_GAINED_TOTAL; 36 import static android.health.connect.datatypes.ExerciseSessionRecord.EXERCISE_DURATION_TOTAL; 37 import static android.health.connect.datatypes.FloorsClimbedRecord.FLOORS_CLIMBED_TOTAL; 38 import static android.health.connect.datatypes.HeartRateRecord.BPM_AVG; 39 import static android.health.connect.datatypes.HeartRateRecord.BPM_MAX; 40 import static android.health.connect.datatypes.HeartRateRecord.BPM_MIN; 41 import static android.health.connect.datatypes.HeartRateRecord.HEART_MEASUREMENTS_COUNT; 42 import static android.health.connect.datatypes.HeightRecord.HEIGHT_AVG; 43 import static android.health.connect.datatypes.HeightRecord.HEIGHT_MAX; 44 import static android.health.connect.datatypes.HeightRecord.HEIGHT_MIN; 45 import static android.health.connect.datatypes.HydrationRecord.VOLUME_TOTAL; 46 import static android.health.connect.datatypes.MindfulnessSessionRecord.MINDFULNESS_DURATION_TOTAL; 47 import static android.health.connect.datatypes.NutritionRecord.BIOTIN_TOTAL; 48 import static android.health.connect.datatypes.NutritionRecord.CAFFEINE_TOTAL; 49 import static android.health.connect.datatypes.NutritionRecord.CALCIUM_TOTAL; 50 import static android.health.connect.datatypes.NutritionRecord.CHLORIDE_TOTAL; 51 import static android.health.connect.datatypes.NutritionRecord.CHOLESTEROL_TOTAL; 52 import static android.health.connect.datatypes.NutritionRecord.CHROMIUM_TOTAL; 53 import static android.health.connect.datatypes.NutritionRecord.COPPER_TOTAL; 54 import static android.health.connect.datatypes.NutritionRecord.DIETARY_FIBER_TOTAL; 55 import static android.health.connect.datatypes.NutritionRecord.ENERGY_FROM_FAT_TOTAL; 56 import static android.health.connect.datatypes.NutritionRecord.ENERGY_TOTAL; 57 import static android.health.connect.datatypes.NutritionRecord.FOLATE_TOTAL; 58 import static android.health.connect.datatypes.NutritionRecord.FOLIC_ACID_TOTAL; 59 import static android.health.connect.datatypes.NutritionRecord.IODINE_TOTAL; 60 import static android.health.connect.datatypes.NutritionRecord.IRON_TOTAL; 61 import static android.health.connect.datatypes.NutritionRecord.MAGNESIUM_TOTAL; 62 import static android.health.connect.datatypes.NutritionRecord.MANGANESE_TOTAL; 63 import static android.health.connect.datatypes.NutritionRecord.MOLYBDENUM_TOTAL; 64 import static android.health.connect.datatypes.NutritionRecord.MONOUNSATURATED_FAT_TOTAL; 65 import static android.health.connect.datatypes.NutritionRecord.NIACIN_TOTAL; 66 import static android.health.connect.datatypes.NutritionRecord.PANTOTHENIC_ACID_TOTAL; 67 import static android.health.connect.datatypes.NutritionRecord.PHOSPHORUS_TOTAL; 68 import static android.health.connect.datatypes.NutritionRecord.POLYUNSATURATED_FAT_TOTAL; 69 import static android.health.connect.datatypes.NutritionRecord.POTASSIUM_TOTAL; 70 import static android.health.connect.datatypes.NutritionRecord.PROTEIN_TOTAL; 71 import static android.health.connect.datatypes.NutritionRecord.RIBOFLAVIN_TOTAL; 72 import static android.health.connect.datatypes.NutritionRecord.SATURATED_FAT_TOTAL; 73 import static android.health.connect.datatypes.NutritionRecord.SELENIUM_TOTAL; 74 import static android.health.connect.datatypes.NutritionRecord.SODIUM_TOTAL; 75 import static android.health.connect.datatypes.NutritionRecord.SUGAR_TOTAL; 76 import static android.health.connect.datatypes.NutritionRecord.THIAMIN_TOTAL; 77 import static android.health.connect.datatypes.NutritionRecord.TOTAL_CARBOHYDRATE_TOTAL; 78 import static android.health.connect.datatypes.NutritionRecord.TOTAL_FAT_TOTAL; 79 import static android.health.connect.datatypes.NutritionRecord.TRANS_FAT_TOTAL; 80 import static android.health.connect.datatypes.NutritionRecord.UNSATURATED_FAT_TOTAL; 81 import static android.health.connect.datatypes.NutritionRecord.VITAMIN_A_TOTAL; 82 import static android.health.connect.datatypes.NutritionRecord.VITAMIN_B12_TOTAL; 83 import static android.health.connect.datatypes.NutritionRecord.VITAMIN_B6_TOTAL; 84 import static android.health.connect.datatypes.NutritionRecord.VITAMIN_C_TOTAL; 85 import static android.health.connect.datatypes.NutritionRecord.VITAMIN_D_TOTAL; 86 import static android.health.connect.datatypes.NutritionRecord.VITAMIN_E_TOTAL; 87 import static android.health.connect.datatypes.NutritionRecord.VITAMIN_K_TOTAL; 88 import static android.health.connect.datatypes.NutritionRecord.ZINC_TOTAL; 89 import static android.health.connect.datatypes.PowerRecord.POWER_AVG; 90 import static android.health.connect.datatypes.PowerRecord.POWER_MAX; 91 import static android.health.connect.datatypes.PowerRecord.POWER_MIN; 92 import static android.health.connect.datatypes.SkinTemperatureRecord.SKIN_TEMPERATURE_DELTA_AVG; 93 import static android.health.connect.datatypes.SkinTemperatureRecord.SKIN_TEMPERATURE_DELTA_MAX; 94 import static android.health.connect.datatypes.SkinTemperatureRecord.SKIN_TEMPERATURE_DELTA_MIN; 95 import static android.health.connect.datatypes.SleepSessionRecord.SLEEP_DURATION_TOTAL; 96 import static android.health.connect.datatypes.SpeedRecord.SPEED_AVG; 97 import static android.health.connect.datatypes.SpeedRecord.SPEED_MAX; 98 import static android.health.connect.datatypes.SpeedRecord.SPEED_MIN; 99 import static android.health.connect.datatypes.StepsCadenceRecord.STEPS_CADENCE_RATE_AVG; 100 import static android.health.connect.datatypes.StepsCadenceRecord.STEPS_CADENCE_RATE_MAX; 101 import static android.health.connect.datatypes.StepsCadenceRecord.STEPS_CADENCE_RATE_MIN; 102 import static android.health.connect.datatypes.StepsRecord.STEPS_COUNT_TOTAL; 103 import static android.health.connect.datatypes.WeightRecord.WEIGHT_AVG; 104 import static android.health.connect.datatypes.WeightRecord.WEIGHT_MAX; 105 import static android.health.connect.datatypes.WeightRecord.WEIGHT_MIN; 106 import static android.health.connect.datatypes.WheelchairPushesRecord.WHEEL_CHAIR_PUSHES_COUNT_TOTAL; 107 108 import android.annotation.NonNull; 109 import android.health.connect.AggregateResult; 110 import android.health.connect.datatypes.AggregationType; 111 import android.health.connect.datatypes.RestingHeartRateRecord; 112 import android.health.connect.datatypes.TotalCaloriesBurnedRecord; 113 import android.health.connect.datatypes.units.Energy; 114 import android.health.connect.datatypes.units.Length; 115 import android.health.connect.datatypes.units.Mass; 116 import android.health.connect.datatypes.units.Power; 117 import android.health.connect.datatypes.units.Pressure; 118 import android.health.connect.datatypes.units.TemperatureDelta; 119 import android.health.connect.datatypes.units.Velocity; 120 import android.health.connect.datatypes.units.Volume; 121 import android.os.Parcel; 122 123 import com.android.healthfitness.flags.AconfigFlagHelper; 124 import com.android.healthfitness.flags.Flags; 125 126 import java.time.Duration; 127 import java.util.ArrayList; 128 import java.util.Arrays; 129 import java.util.HashMap; 130 import java.util.List; 131 import java.util.Map; 132 133 /** 134 * Creates and maintains a map of {@link AggregationType.AggregationTypeIdentifier} to {@link 135 * AggregationType} and its result creator {@link AggregationResultCreator} 136 * 137 * @hide 138 */ 139 public final class AggregationTypeIdMapper { 140 @SuppressWarnings("NullAway.Init") // TODO(b/317029272): fix this suppression 141 private static volatile AggregationTypeIdMapper sAggregationTypeIdMapper; 142 143 private final Map<Integer, AggregationResultCreator> mIdToAggregateResult; 144 private final Map<Integer, AggregationType<?>> mIdDataAggregationTypeMap; 145 private final Map<AggregationType<?>, Integer> mDataAggregationTypeIdMap; 146 AggregationTypeIdMapper()147 private AggregationTypeIdMapper() { 148 mIdToAggregateResult = new HashMap<>(); 149 mIdDataAggregationTypeMap = new HashMap<>(); 150 mDataAggregationTypeIdMap = new HashMap<>(); 151 152 List<AggregationType<?>> longAggregations = 153 new ArrayList<>( 154 List.of( 155 BPM_MAX, 156 BPM_MIN, 157 STEPS_COUNT_TOTAL, 158 BPM_AVG, 159 RestingHeartRateRecord.BPM_MAX, 160 RestingHeartRateRecord.BPM_MIN, 161 RestingHeartRateRecord.BPM_AVG, 162 WHEEL_CHAIR_PUSHES_COUNT_TOTAL, 163 HEART_MEASUREMENTS_COUNT, 164 SLEEP_DURATION_TOTAL, 165 EXERCISE_DURATION_TOTAL, 166 MINDFULNESS_DURATION_TOTAL)); 167 List<AggregationType<?>> durationAggregations = new ArrayList<>(); 168 169 // Redundantly explicitly checking the flag to satisfy the linter. 170 if (Flags.activityIntensity() && AconfigFlagHelper.isActivityIntensityEnabled()) { 171 durationAggregations.add(MODERATE_DURATION_TOTAL); 172 durationAggregations.add(VIGOROUS_DURATION_TOTAL); 173 durationAggregations.add(DURATION_TOTAL); 174 longAggregations.add(INTENSITY_MINUTES_TOTAL); 175 } 176 177 addLongIdsToAggregateResultMap(longAggregations); 178 addDoubleIdsToAggregateResultMap( 179 Arrays.asList( 180 FLOORS_CLIMBED_TOTAL, 181 RPM_AVG, 182 RPM_MAX, 183 RPM_MIN, 184 STEPS_CADENCE_RATE_MAX, 185 STEPS_CADENCE_RATE_AVG, 186 STEPS_CADENCE_RATE_MIN)); 187 addPowerIdsToAggregateResultMap(Arrays.asList(POWER_MIN, POWER_MAX, POWER_AVG)); 188 addTemperatureDeltaIdsToAggregateResultMap( 189 Arrays.asList( 190 SKIN_TEMPERATURE_DELTA_AVG, 191 SKIN_TEMPERATURE_DELTA_MIN, 192 SKIN_TEMPERATURE_DELTA_MAX)); 193 addEnergyIdsToAggregateResultMap( 194 Arrays.asList( 195 ACTIVE_CALORIES_TOTAL, 196 BASAL_CALORIES_TOTAL, 197 ENERGY_TOTAL, 198 ENERGY_FROM_FAT_TOTAL, 199 TotalCaloriesBurnedRecord.ENERGY_TOTAL)); 200 addVolumeIdsToAggregateResultMap(Arrays.asList(VOLUME_TOTAL)); 201 addLengthIdsToAggregateResultMap( 202 Arrays.asList( 203 DISTANCE_TOTAL, 204 ELEVATION_GAINED_TOTAL, 205 HEIGHT_AVG, 206 HEIGHT_MAX, 207 HEIGHT_MIN)); 208 addMassIdsToAggregateResultMap( 209 Arrays.asList( 210 BIOTIN_TOTAL, 211 CAFFEINE_TOTAL, 212 CALCIUM_TOTAL, 213 CHLORIDE_TOTAL, 214 CHOLESTEROL_TOTAL, 215 CHROMIUM_TOTAL, 216 COPPER_TOTAL, 217 DIETARY_FIBER_TOTAL, 218 FOLATE_TOTAL, 219 FOLIC_ACID_TOTAL, 220 IODINE_TOTAL, 221 IRON_TOTAL, 222 MAGNESIUM_TOTAL, 223 MANGANESE_TOTAL, 224 MOLYBDENUM_TOTAL, 225 MONOUNSATURATED_FAT_TOTAL, 226 NIACIN_TOTAL, 227 PANTOTHENIC_ACID_TOTAL, 228 PHOSPHORUS_TOTAL, 229 POLYUNSATURATED_FAT_TOTAL, 230 POTASSIUM_TOTAL, 231 PROTEIN_TOTAL, 232 RIBOFLAVIN_TOTAL, 233 SATURATED_FAT_TOTAL, 234 SELENIUM_TOTAL, 235 SODIUM_TOTAL, 236 SUGAR_TOTAL, 237 THIAMIN_TOTAL, 238 TOTAL_CARBOHYDRATE_TOTAL, 239 TOTAL_FAT_TOTAL, 240 UNSATURATED_FAT_TOTAL, 241 VITAMIN_A_TOTAL, 242 VITAMIN_B12_TOTAL, 243 VITAMIN_B6_TOTAL, 244 VITAMIN_C_TOTAL, 245 VITAMIN_D_TOTAL, 246 VITAMIN_E_TOTAL, 247 VITAMIN_K_TOTAL, 248 ZINC_TOTAL, 249 WEIGHT_AVG, 250 WEIGHT_MAX, 251 WEIGHT_MIN, 252 TRANS_FAT_TOTAL)); 253 addVelocityIdsToAggregateResultMap(Arrays.asList(SPEED_MAX, SPEED_AVG, SPEED_MIN)); 254 addPressureIdsToAggregateResultMap( 255 Arrays.asList( 256 DIASTOLIC_AVG, 257 DIASTOLIC_MAX, 258 DIASTOLIC_MIN, 259 SYSTOLIC_AVG, 260 SYSTOLIC_MAX, 261 SYSTOLIC_MIN)); 262 addDurationIdsToAggregateResultMap(durationAggregations); 263 } 264 265 @NonNull getInstance()266 public static synchronized AggregationTypeIdMapper getInstance() { 267 if (sAggregationTypeIdMapper == null) { 268 sAggregationTypeIdMapper = new AggregationTypeIdMapper(); 269 } 270 271 return sAggregationTypeIdMapper; 272 } 273 274 @SuppressWarnings("NullAway") // TODO(b/317029272): fix this suppression 275 @NonNull getAggregateResultFor( @ggregationType.AggregationTypeIdentifier.Id int id, @NonNull Parcel parcel)276 public AggregateResult<?> getAggregateResultFor( 277 @AggregationType.AggregationTypeIdentifier.Id int id, @NonNull Parcel parcel) { 278 return mIdToAggregateResult.get(id).getAggregateResult(parcel); 279 } 280 281 @SuppressWarnings("NullAway") // TODO(b/317029272): fix this suppression 282 @NonNull getAggregationTypeFor( @ggregationType.AggregationTypeIdentifier.Id int id)283 public AggregationType<?> getAggregationTypeFor( 284 @AggregationType.AggregationTypeIdentifier.Id int id) { 285 return mIdDataAggregationTypeMap.get(id); 286 } 287 288 @SuppressWarnings("NullAway") // TODO(b/317029272): fix this suppression 289 @NonNull 290 @AggregationType.AggregationTypeIdentifier.Id getIdFor(AggregationType<?> aggregationType)291 public int getIdFor(AggregationType<?> aggregationType) { 292 return mDataAggregationTypeIdMap.get(aggregationType); 293 } 294 295 @NonNull getLongResult(long result)296 private AggregateResult<Long> getLongResult(long result) { 297 return new AggregateResult<>(result); 298 } 299 300 @NonNull getDoubleResult(double result)301 private AggregateResult<Double> getDoubleResult(double result) { 302 return new AggregateResult<>(result); 303 } 304 305 @NonNull getEnergyResult(double result)306 private AggregateResult<Energy> getEnergyResult(double result) { 307 return new AggregateResult<>(Energy.fromCalories(result)); 308 } 309 310 @NonNull getPowerResult(double result)311 private AggregateResult<Power> getPowerResult(double result) { 312 return new AggregateResult<>(Power.fromWatts(result)); 313 } 314 315 @NonNull getTemperatureDeltaResult(double result)316 private AggregateResult<TemperatureDelta> getTemperatureDeltaResult(double result) { 317 return new AggregateResult<>(TemperatureDelta.fromCelsius(result)); 318 } 319 320 @NonNull getPressureResult(double result)321 private AggregateResult<Pressure> getPressureResult(double result) { 322 return new AggregateResult<>(Pressure.fromMillimetersOfMercury(result)); 323 } 324 325 @NonNull getLengthResult(double result)326 private AggregateResult<Length> getLengthResult(double result) { 327 return new AggregateResult<>(Length.fromMeters(result)); 328 } 329 330 @NonNull getVolumeResult(double result)331 private AggregateResult<Volume> getVolumeResult(double result) { 332 return new AggregateResult<>(Volume.fromLiters(result)); 333 } 334 335 @NonNull getMassResult(double result)336 private AggregateResult<Mass> getMassResult(double result) { 337 return new AggregateResult<>(Mass.fromGrams(result)); 338 } 339 340 @NonNull getVelocityResult(double result)341 private AggregateResult<Velocity> getVelocityResult(double result) { 342 return new AggregateResult<>(Velocity.fromMetersPerSecond(result)); 343 } 344 345 @NonNull getDurationResult(long resultMillis)346 private AggregateResult<Duration> getDurationResult(long resultMillis) { 347 return new AggregateResult<>(Duration.ofMillis(resultMillis)); 348 } 349 addLongIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)350 private void addLongIdsToAggregateResultMap( 351 @NonNull List<AggregationType<?>> aggregationTypeList) { 352 for (AggregationType<?> aggregationType : aggregationTypeList) { 353 mIdToAggregateResult.put( 354 aggregationType.getAggregationTypeIdentifier(), 355 result -> getLongResult(result.readLong())); 356 populateIdDataAggregationType(aggregationType); 357 } 358 } 359 addDoubleIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)360 private void addDoubleIdsToAggregateResultMap( 361 @NonNull List<AggregationType<?>> aggregationTypeList) { 362 for (AggregationType<?> aggregationType : aggregationTypeList) { 363 mIdToAggregateResult.put( 364 aggregationType.getAggregationTypeIdentifier(), 365 result -> getDoubleResult(result.readDouble())); 366 populateIdDataAggregationType(aggregationType); 367 } 368 } 369 addEnergyIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)370 private void addEnergyIdsToAggregateResultMap( 371 @NonNull List<AggregationType<?>> aggregationTypeList) { 372 for (AggregationType<?> aggregationType : aggregationTypeList) { 373 mIdToAggregateResult.put( 374 aggregationType.getAggregationTypeIdentifier(), 375 result -> getEnergyResult(result.readDouble())); 376 populateIdDataAggregationType(aggregationType); 377 } 378 } 379 addPowerIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)380 private void addPowerIdsToAggregateResultMap( 381 @NonNull List<AggregationType<?>> aggregationTypeList) { 382 for (AggregationType<?> aggregationType : aggregationTypeList) { 383 mIdToAggregateResult.put( 384 aggregationType.getAggregationTypeIdentifier(), 385 result -> getPowerResult(result.readDouble())); 386 populateIdDataAggregationType(aggregationType); 387 } 388 } 389 addTemperatureDeltaIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)390 private void addTemperatureDeltaIdsToAggregateResultMap( 391 @NonNull List<AggregationType<?>> aggregationTypeList) { 392 for (AggregationType<?> aggregationType : aggregationTypeList) { 393 mIdToAggregateResult.put( 394 aggregationType.getAggregationTypeIdentifier(), 395 result -> getTemperatureDeltaResult(result.readDouble())); 396 populateIdDataAggregationType(aggregationType); 397 } 398 } 399 addPressureIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)400 private void addPressureIdsToAggregateResultMap( 401 @NonNull List<AggregationType<?>> aggregationTypeList) { 402 for (AggregationType<?> aggregationType : aggregationTypeList) { 403 mIdToAggregateResult.put( 404 aggregationType.getAggregationTypeIdentifier(), 405 result -> getPressureResult(result.readDouble())); 406 populateIdDataAggregationType(aggregationType); 407 } 408 } 409 addLengthIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)410 private void addLengthIdsToAggregateResultMap( 411 @NonNull List<AggregationType<?>> aggregationTypeList) { 412 for (AggregationType<?> aggregationType : aggregationTypeList) { 413 mIdToAggregateResult.put( 414 aggregationType.getAggregationTypeIdentifier(), 415 result -> getLengthResult(result.readDouble())); 416 populateIdDataAggregationType(aggregationType); 417 } 418 } 419 addVolumeIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)420 private void addVolumeIdsToAggregateResultMap( 421 @NonNull List<AggregationType<?>> aggregationTypeList) { 422 for (AggregationType<?> aggregationType : aggregationTypeList) { 423 mIdToAggregateResult.put( 424 aggregationType.getAggregationTypeIdentifier(), 425 result -> getVolumeResult(result.readDouble())); 426 populateIdDataAggregationType(aggregationType); 427 } 428 } 429 addMassIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)430 private void addMassIdsToAggregateResultMap( 431 @NonNull List<AggregationType<?>> aggregationTypeList) { 432 for (AggregationType<?> aggregationType : aggregationTypeList) { 433 mIdToAggregateResult.put( 434 aggregationType.getAggregationTypeIdentifier(), 435 result -> getMassResult(result.readDouble())); 436 populateIdDataAggregationType(aggregationType); 437 } 438 } 439 addVelocityIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)440 private void addVelocityIdsToAggregateResultMap( 441 @NonNull List<AggregationType<?>> aggregationTypeList) { 442 for (AggregationType<?> aggregationType : aggregationTypeList) { 443 mIdToAggregateResult.put( 444 aggregationType.getAggregationTypeIdentifier(), 445 result -> getVelocityResult(result.readDouble())); 446 populateIdDataAggregationType(aggregationType); 447 } 448 } 449 addDurationIdsToAggregateResultMap( @onNull List<AggregationType<?>> aggregationTypeList)450 private void addDurationIdsToAggregateResultMap( 451 @NonNull List<AggregationType<?>> aggregationTypeList) { 452 for (AggregationType<?> aggregationType : aggregationTypeList) { 453 mIdToAggregateResult.put( 454 aggregationType.getAggregationTypeIdentifier(), 455 result -> getDurationResult(result.readLong())); 456 populateIdDataAggregationType(aggregationType); 457 } 458 } 459 populateIdDataAggregationType(AggregationType<?> aggregationType)460 private void populateIdDataAggregationType(AggregationType<?> aggregationType) { 461 mIdDataAggregationTypeMap.put( 462 aggregationType.getAggregationTypeIdentifier(), aggregationType); 463 mDataAggregationTypeIdMap.put( 464 aggregationType, aggregationType.getAggregationTypeIdentifier()); 465 } 466 467 /** 468 * Implementation should get and covert result to appropriate type (such as long, double etc.) 469 * using {@code result} 470 */ 471 private interface AggregationResultCreator { getAggregateResult(Parcel result)472 AggregateResult<?> getAggregateResult(Parcel result); 473 } 474 } 475