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.testapps.toolbox.utils 17 18 import android.content.Context 19 import android.health.connect.HealthConnectManager 20 import android.health.connect.InsertRecordsResponse 21 import android.health.connect.ReadRecordsRequestUsingFilters 22 import android.health.connect.ReadRecordsResponse 23 import android.health.connect.TimeRangeFilter 24 import android.health.connect.datatypes.DataOrigin 25 import android.health.connect.datatypes.Device 26 import android.health.connect.datatypes.Metadata 27 import android.health.connect.datatypes.Record 28 import android.os.Build.MANUFACTURER 29 import android.os.Build.MODEL 30 import android.util.Log 31 import androidx.core.os.asOutcomeReceiver 32 import java.lang.reflect.Field 33 import java.lang.reflect.Modifier 34 import kotlin.reflect.KClass 35 import kotlinx.coroutines.suspendCancellableCoroutine 36 37 class GeneralUtils { 38 39 companion object { 40 fun getMetaData(context: Context, recordUuid: String): Metadata { 41 val device: Device = 42 Device.Builder().setManufacturer(MANUFACTURER).setModel(MODEL).setType(1).build() 43 val dataOrigin = DataOrigin.Builder().setPackageName(context.packageName).build() 44 return Metadata.Builder() 45 .setDevice(device) 46 .setDataOrigin(dataOrigin) 47 .setId(recordUuid) 48 .build() 49 } 50 51 fun getMetaData(context: Context): Metadata { 52 val device: Device = 53 Device.Builder().setManufacturer(MANUFACTURER).setModel(MODEL).setType(1).build() 54 val dataOrigin = DataOrigin.Builder().setPackageName(context.packageName).build() 55 return Metadata.Builder().setDevice(device).setDataOrigin(dataOrigin).build() 56 } 57 58 suspend fun <T : Record> insertRecords( 59 records: List<T>, 60 manager: HealthConnectManager, 61 ): List<Record> { 62 63 val insertedRecords = 64 try { 65 suspendCancellableCoroutine<InsertRecordsResponse> { continuation -> 66 manager.insertRecords( 67 records, Runnable::run, continuation.asOutcomeReceiver()) 68 } 69 .records 70 } catch (ex: Exception) { 71 throw ex 72 } 73 return insertedRecords 74 } 75 76 suspend fun <T : Record> updateRecords( 77 records: List<T>, 78 manager: HealthConnectManager, 79 ) { 80 try { 81 suspendCancellableCoroutine<Void> { continuation -> 82 manager.updateRecords(records, Runnable::run, continuation.asOutcomeReceiver()) 83 } 84 } catch (ex: Exception) { 85 throw ex 86 } 87 } 88 89 fun <T : Any> getStaticFieldNamesAndValues( 90 obj: KClass<T>, 91 ): EnumFieldsWithValues { 92 val fieldNameToValue: MutableMap<String, Any> = emptyMap<String, Any>().toMutableMap() 93 val fields: List<Field> = 94 obj.java.declaredFields.filter { field -> 95 Modifier.isStatic(field.modifiers) && 96 field.type == Int::class.java 97 } 98 for (field in fields) { 99 fieldNameToValue[field.name] = field.get(obj)!! 100 } 101 return EnumFieldsWithValues(fieldNameToValue.toMap()) 102 } 103 104 suspend fun readRecords( 105 recordType: Class<out Record>, 106 timeFilterRange: TimeRangeFilter, 107 numberOfRecordsPerBatch: Long, 108 manager: HealthConnectManager, 109 ): List<Record> { 110 val filter = 111 ReadRecordsRequestUsingFilters.Builder(recordType) 112 .setTimeRangeFilter(timeFilterRange) 113 .setPageSize(numberOfRecordsPerBatch.toInt()) 114 .build() 115 val records = 116 suspendCancellableCoroutine<ReadRecordsResponse<*>> { continuation -> 117 manager.readRecords(filter, Runnable::run, continuation.asOutcomeReceiver()) 118 } 119 .records 120 Log.d("READ_RECORDS", "Read ${records.size} records") 121 return records 122 } 123 } 124 } 125