1 /*
<lambda>null2  * 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 package com.android.healthconnect.controller.datasources
17 
18 import android.os.Bundle
19 import android.view.View
20 import androidx.fragment.app.activityViewModels
21 import com.android.healthconnect.controller.R
22 import com.android.healthconnect.controller.categories.HealthDataCategoriesFragment.Companion.CATEGORY_KEY
23 import com.android.healthconnect.controller.datasources.DataSourcesViewModel.PotentialAppSourcesState
24 import com.android.healthconnect.controller.datasources.DataSourcesViewModel.PriorityListState
25 import com.android.healthconnect.controller.shared.HealthDataCategoryInt
26 import com.android.healthconnect.controller.shared.app.AppMetadata
27 import com.android.healthconnect.controller.shared.preference.HealthPreference
28 import com.android.healthconnect.controller.shared.preference.HealthPreferenceFragment
29 import com.android.healthconnect.controller.utils.NavigationUtils
30 import com.android.healthconnect.controller.utils.logging.AddAnAppElement
31 import com.android.healthconnect.controller.utils.logging.PageName
32 import dagger.hilt.android.AndroidEntryPoint
33 import javax.inject.Inject
34 
35 @AndroidEntryPoint(HealthPreferenceFragment::class)
36 class AddAnAppFragment : Hilt_AddAnAppFragment() {
37 
38     private val dataSourcesViewModel: DataSourcesViewModel by activityViewModels()
39     @HealthDataCategoryInt private var category: Int = 0
40     @Inject lateinit var navigationUtils: NavigationUtils
41 
42     private var currentPriority: List<AppMetadata> = listOf()
43 
44     init {
45         this.setPageName(PageName.ADD_AN_APP_PAGE)
46     }
47 
48     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
49         super.onCreatePreferences(savedInstanceState, rootKey)
50         setPreferencesFromResource(R.xml.add_an_app_screen, rootKey)
51         if (requireArguments().containsKey(CATEGORY_KEY)) {
52             category = requireArguments().getInt(CATEGORY_KEY)
53         }
54     }
55 
56     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
57         super.onViewCreated(view, savedInstanceState)
58 
59         dataSourcesViewModel.loadData(category)
60         dataSourcesViewModel.dataSourcesInfo.observe(viewLifecycleOwner) { dataSourcesInfoState ->
61             if (dataSourcesInfoState.isLoading()) {
62                 setLoading(true)
63             } else if (dataSourcesInfoState.isLoadingFailed()) {
64                 setLoading(false)
65                 setError(true)
66             } else if (dataSourcesInfoState.isWithData()) {
67                 setLoading(false)
68                 val currentPriorityList =
69                     (dataSourcesInfoState.priorityListState as PriorityListState.WithData)
70                         .priorityList
71                 val potentialAppSources =
72                     (dataSourcesInfoState.potentialAppSourcesState
73                             as PotentialAppSourcesState.WithData)
74                         .appSources
75                 currentPriorityList.let { currentPriority = it }
76                 updateAppsList(potentialAppSources)
77             }
78         }
79     }
80 
81     private fun updateAppsList(appSources: List<AppMetadata>) {
82         preferenceScreen.removeAll()
83         appSources
84             .sortedBy { it.appName }
85             .forEach { appMetadata ->
86                 preferenceScreen.addPreference(
87                     HealthPreference(requireContext()).also { preference ->
88                         preference.title = appMetadata.appName
89                         preference.icon = appMetadata.icon
90                         preference.logName = AddAnAppElement.POTENTIAL_PRIORITY_APP_BUTTON
91                         preference.setOnPreferenceClickListener {
92                             // add this app to the bottom of the priority list
93                             val newPriority =
94                                 currentPriority
95                                     .toMutableList()
96                                     .also { it.add(appMetadata) }
97                                     .toList()
98                             dataSourcesViewModel.updatePriorityList(
99                                 newPriority.map { it.packageName }.toList(), category)
100                             navigationUtils.popBackStack(this)
101                             true
102                         }
103                     })
104             }
105     }
106 }
107