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.healthconnect.controller.data.access
18 
19 import androidx.lifecycle.LiveData
20 import androidx.lifecycle.MutableLiveData
21 import androidx.lifecycle.ViewModel
22 import androidx.lifecycle.viewModelScope
23 import com.android.healthconnect.controller.data.access.AccessViewModel.AccessScreenState.Error
24 import com.android.healthconnect.controller.data.access.AccessViewModel.AccessScreenState.WithData
25 import com.android.healthconnect.controller.permissions.data.HealthPermissionType
26 import com.android.healthconnect.controller.shared.app.AppMetadata
27 import com.android.healthconnect.controller.shared.usecase.UseCaseResults
28 import com.android.healthconnect.controller.utils.postValueIfUpdated
29 import dagger.hilt.android.lifecycle.HiltViewModel
30 import javax.inject.Inject
31 import kotlinx.coroutines.launch
32 
33 /**
34  * View model for the Access tab in [EntriesAccessFragment] and
35  * [com.android.healthconnect.controller.dataaccess.HealthDataAccessFragment].
36  */
37 @HiltViewModel
38 class AccessViewModel @Inject constructor(private val loadAccessUseCase: ILoadAccessUseCase) :
39     ViewModel() {
40 
41     private val _appMetadataMap = MutableLiveData<AccessScreenState>()
42 
43     val appMetadataMap: LiveData<AccessScreenState>
44         get() = _appMetadataMap
45 
loadAppMetaDataMapnull46     fun loadAppMetaDataMap(permissionType: HealthPermissionType) {
47         val appsMap = _appMetadataMap.value
48         if (appsMap is WithData && appsMap.appMetadata.isEmpty()) {
49             _appMetadataMap.postValue(AccessScreenState.Loading)
50         }
51         viewModelScope.launch {
52             when (val result = loadAccessUseCase.invoke(permissionType)) {
53                 is UseCaseResults.Success -> {
54                     _appMetadataMap.postValueIfUpdated(WithData(result.data))
55                 }
56                 else -> {
57                     _appMetadataMap.postValue(Error)
58                 }
59             }
60         }
61     }
62 
63     /** Represents DataAccessFragment state. */
64     sealed class AccessScreenState {
65         object Loading : AccessScreenState()
66 
67         object Error : AccessScreenState()
68 
69         data class WithData(val appMetadata: Map<AppAccessState, List<AppMetadata>>) :
70             AccessScreenState()
71     }
72 }
73