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 
44     /** Holds the export settings that is stored in the Health Connect service. */
45     val storedExportSettings: LiveData<ExportSettings>
46         get() = _storedExportSettings
47 
48     /** Holds the previous export frequency that is stored. */
49     val previousExportFrequency: LiveData<ExportFrequency?>
50         get() = _previousExportFrequency
51 
52     /** Holds the user selected export frequency. */
53     val selectedExportFrequency: LiveData<ExportFrequency?>
54         get() = _selectedExportFrequency
55 
56     /** Holds the supported document providers. */
57     val documentProviders: LiveData<DocumentProviders>
58         get() = _documentProviders
59 
60     init {
61         loadExportSettings()
62         loadDocumentProviders()
63         _selectedExportFrequency.value = ExportFrequency.EXPORT_FREQUENCY_NEVER
64     }
65 
66     /** Triggers a load of export settings. */
loadExportSettingsnull67     fun loadExportSettings() {
68         _storedExportSettings.postValue(ExportSettings.Loading)
69         viewModelScope.launch {
70             when (val result = loadExportSettingsUseCase.invoke()) {
71                 is ExportImportUseCaseResult.Success -> {
72                     _storedExportSettings.postValue(ExportSettings.WithData(result.data))
73                 }
74                 is ExportImportUseCaseResult.Failed -> {
75                     _storedExportSettings.postValue(ExportSettings.LoadingFailed)
76                 }
77             }
78         }
79     }
80 
81     /** Triggers a query of the document providers. */
loadDocumentProvidersnull82     fun loadDocumentProviders() {
83         _documentProviders.postValue(DocumentProviders.Loading)
84         viewModelScope.launch {
85             when (val result = queryDocumentProvidersUseCase.invoke()) {
86                 is ExportImportUseCaseResult.Success -> {
87                     _documentProviders.postValue(DocumentProviders.WithData(result.data))
88                 }
89                 is ExportImportUseCaseResult.Failed -> {
90                     _documentProviders.postValue(DocumentProviders.LoadingFailed)
91                 }
92             }
93         }
94     }
95 
96     /** Updates the previous frequency of scheduled exports of Health Connect data. */
updatePreviousExportFrequencynull97     fun updatePreviousExportFrequency(frequency: ExportFrequency) {
98         if (frequency != ExportFrequency.EXPORT_FREQUENCY_NEVER) {
99             _previousExportFrequency.value = frequency
100         }
101     }
102 
103     /** Updates the uri to write to in scheduled exports of Health Connect data. */
updateExportUrinull104     fun updateExportUri(uri: Uri) {
105         val settings = ScheduledExportSettings.withUri(uri)
106         updateExportSettings(settings)
107     }
108 
109     /**
110      * Updates the uri and the selected frequency to write to in scheduled exports of Health Connect
111      * data.
112      */
updateExportUriWithSelectedFrequencynull113     fun updateExportUriWithSelectedFrequency(uri: Uri) {
114         val settings =
115             ScheduledExportSettings.withUriAndPeriodInDays(
116                 uri,
117                 _selectedExportFrequency.value?.periodInDays
118                     ?: ExportFrequency.EXPORT_FREQUENCY_NEVER.periodInDays)
119         updateExportSettings(settings)
120     }
121 
122     /** Updates the frequency of scheduled exports of Health Connect data. */
updateExportFrequencynull123     fun updateExportFrequency(frequency: ExportFrequency) {
124         val settings = ScheduledExportSettings.withPeriodInDays(frequency.periodInDays)
125         updateExportSettings(settings)
126     }
127 
128     /** Updates the stored frequency of scheduled exports of Health Connect data. */
updateSelectedFrequencynull129     fun updateSelectedFrequency(frequency: ExportFrequency) {
130         _selectedExportFrequency.value = frequency
131     }
132 
updateExportSettingsnull133     private fun updateExportSettings(settings: ScheduledExportSettings) {
134         viewModelScope.launch {
135             when (updateExportSettingsUseCase.invoke(settings)) {
136                 is ExportImportUseCaseResult.Success -> {
137                     if (settings.periodInDays != DEFAULT_INT) {
138                         val frequency = fromPeriodInDays(settings.periodInDays)
139                         _storedExportSettings.postValue(ExportSettings.WithData(frequency))
140                     }
141                 }
142                 is ExportImportUseCaseResult.Failed -> {
143                     _storedExportSettings.postValue(ExportSettings.LoadingFailed)
144                 }
145             }
146         }
147     }
148 }
149