1 /* 2 * Copyright (C) 2024 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.healthconnect.controller.exportimport.api 18 19 import android.health.connect.Constants.DEFAULT_INT 20 import android.health.connect.exportimport.ScheduledExportSettings 21 import android.net.Uri 22 import androidx.lifecycle.LiveData 23 import androidx.lifecycle.MutableLiveData 24 import androidx.lifecycle.ViewModel 25 import androidx.lifecycle.viewModelScope 26 import dagger.hilt.android.lifecycle.HiltViewModel 27 import javax.inject.Inject 28 import kotlinx.coroutines.launch 29 30 /** View model for Export settings fragments. */ 31 @HiltViewModel 32 class ExportSettingsViewModel 33 @Inject 34 constructor( 35 private val loadExportSettingsUseCase: ILoadExportSettingsUseCase, 36 private val updateExportSettingsUseCase: IUpdateExportSettingsUseCase, 37 private val queryDocumentProvidersUseCase: IQueryDocumentProvidersUseCase, 38 ) : ViewModel() { 39 private val _storedExportSettings = MutableLiveData<ExportSettings>() 40 private val _selectedExportFrequency = MutableLiveData<ExportFrequency>() 41 private val _previousExportFrequency = MutableLiveData<ExportFrequency?>() 42 private val _documentProviders = MutableLiveData<DocumentProviders>() 43 private val _selectedDocumentProvider = MutableLiveData<DocumentProviderInfo?>() 44 private val _selectedDocumentProviderRoot = MutableLiveData<DocumentProviderRoot?>() 45 private val _selectedRootsForDocumentProviders = 46 MutableLiveData<MutableMap<String, DocumentProviderRoot?>>() 47 48 /** Holds the export settings that is stored in the Health Connect service. */ 49 val storedExportSettings: LiveData<ExportSettings> 50 get() = _storedExportSettings 51 52 /** Holds the previous export frequency that is stored. */ 53 val previousExportFrequency: LiveData<ExportFrequency?> 54 get() = _previousExportFrequency 55 56 /** Holds the user selected export frequency. */ 57 val selectedExportFrequency: LiveData<ExportFrequency?> 58 get() = _selectedExportFrequency 59 60 /** Holds the supported document providers. */ 61 val documentProviders: LiveData<DocumentProviders> 62 get() = _documentProviders 63 64 /** Holds the user selected document provider. */ 65 val selectedDocumentProvider: LiveData<DocumentProviderInfo?> 66 get() = _selectedDocumentProvider 67 68 /** Holds the user selected document provider. */ 69 val selectedDocumentProviderRoot: LiveData<DocumentProviderRoot?> 70 get() = _selectedDocumentProviderRoot 71 72 /** 73 * Holds the user stored document providers. 74 * 75 * This is needed for remembering the user selected account when switching between providers. 76 */ 77 val selectedRootsForDocumentProviders: LiveData<MutableMap<String, DocumentProviderRoot?>> 78 get() = _selectedRootsForDocumentProviders 79 80 init { 81 loadExportSettings() 82 loadDocumentProviders() 83 _selectedExportFrequency.value = ExportFrequency.EXPORT_FREQUENCY_NEVER 84 _selectedRootsForDocumentProviders.value = mutableMapOf() 85 } 86 87 /** Triggers a load of export settings. */ loadExportSettingsnull88 fun loadExportSettings() { 89 _storedExportSettings.postValue(ExportSettings.Loading) 90 viewModelScope.launch { 91 when (val result = loadExportSettingsUseCase.invoke()) { 92 is ExportImportUseCaseResult.Success -> { 93 _storedExportSettings.postValue(ExportSettings.WithData(result.data)) 94 } 95 is ExportImportUseCaseResult.Failed -> { 96 _storedExportSettings.postValue(ExportSettings.LoadingFailed) 97 } 98 } 99 } 100 } 101 102 /** Triggers a query of the document providers. */ loadDocumentProvidersnull103 fun loadDocumentProviders() { 104 _documentProviders.postValue(DocumentProviders.Loading) 105 viewModelScope.launch { 106 when (val result = queryDocumentProvidersUseCase.invoke()) { 107 is ExportImportUseCaseResult.Success -> { 108 _documentProviders.postValue(DocumentProviders.WithData(result.data)) 109 } 110 is ExportImportUseCaseResult.Failed -> { 111 _documentProviders.postValue(DocumentProviders.LoadingFailed) 112 } 113 } 114 } 115 } 116 117 /** Updates the previous frequency of scheduled exports of Health Connect data. */ updatePreviousExportFrequencynull118 fun updatePreviousExportFrequency(frequency: ExportFrequency) { 119 if (frequency != ExportFrequency.EXPORT_FREQUENCY_NEVER) { 120 _previousExportFrequency.value = frequency 121 } 122 } 123 124 /** Updates the uri to write to in scheduled exports of Health Connect data. */ updateExportUrinull125 fun updateExportUri(uri: Uri) { 126 val settings = ScheduledExportSettings.Builder().setUri(uri).build() 127 updateExportSettings(settings) 128 } 129 130 /** 131 * Updates the uri and the selected frequency to write to in scheduled exports of Health Connect 132 * data. 133 */ updateExportUriWithSelectedFrequencynull134 fun updateExportUriWithSelectedFrequency(uri: Uri) { 135 val settings = 136 ScheduledExportSettings.Builder() 137 .setPeriodInDays( 138 _selectedExportFrequency.value?.periodInDays 139 ?: ExportFrequency.EXPORT_FREQUENCY_NEVER.periodInDays 140 ) 141 .setUri(uri) 142 .build() 143 updateExportSettings(settings) 144 } 145 146 /** Updates the frequency of scheduled exports of Health Connect data. */ updateExportFrequencynull147 fun updateExportFrequency(frequency: ExportFrequency) { 148 val settings = 149 ScheduledExportSettings.Builder().setPeriodInDays(frequency.periodInDays).build() 150 updateExportSettings(settings) 151 } 152 153 /** Updates the stored frequency of scheduled exports of Health Connect data. */ updateSelectedFrequencynull154 fun updateSelectedFrequency(frequency: ExportFrequency) { 155 _selectedExportFrequency.value = frequency 156 } 157 158 /** Updates the selected document provider. */ updateSelectedDocumentProvidernull159 fun updateSelectedDocumentProvider( 160 documentProvider: DocumentProviderInfo, 161 documentProviderRoot: DocumentProviderRoot, 162 ) { 163 _selectedDocumentProvider.value = documentProvider 164 _selectedDocumentProviderRoot.value = documentProviderRoot 165 _selectedRootsForDocumentProviders.value?.set(documentProvider.title, documentProviderRoot) 166 } 167 updateExportSettingsnull168 private fun updateExportSettings(settings: ScheduledExportSettings) { 169 viewModelScope.launch { 170 when (updateExportSettingsUseCase.invoke(settings)) { 171 is ExportImportUseCaseResult.Success -> { 172 if (settings.periodInDays != DEFAULT_INT) { 173 val frequency = fromPeriodInDays(settings.periodInDays) 174 _storedExportSettings.postValue(ExportSettings.WithData(frequency)) 175 } 176 } 177 is ExportImportUseCaseResult.Failed -> { 178 _storedExportSettings.postValue(ExportSettings.LoadingFailed) 179 } 180 } 181 } 182 } 183 } 184