• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.permissioncontroller.permission.ui.model
18 
19 import android.Manifest
20 import android.app.Application
21 import android.content.Intent
22 import android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP
23 import android.os.Bundle
24 import androidx.fragment.app.Fragment
25 import androidx.lifecycle.AndroidViewModel
26 import androidx.lifecycle.MutableLiveData
27 import androidx.lifecycle.ViewModel
28 import androidx.lifecycle.ViewModelProvider
29 import androidx.navigation.fragment.findNavController
30 import com.android.permission.flags.Flags
31 import com.android.permissioncontroller.R
32 import com.android.permissioncontroller.permission.data.PermGroupsPackagesLiveData
33 import com.android.permissioncontroller.permission.data.PermGroupsPackagesUiInfoLiveData
34 import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData
35 import com.android.permissioncontroller.permission.utils.Utils
36 import com.android.permissioncontroller.permission.utils.navigateSafe
37 
38 /**
39  * A ViewModel for the ManageCustomPermissionsFragment. Provides a LiveData which watches over all
40  * custom permission groups, and sends async updates when these groups have changes.
41  *
42  * @param app The current application of the fragment
43  */
44 class ManageCustomPermissionsViewModel(private val app: Application) : AndroidViewModel(app) {
45 
46     val uiDataLiveData = PermGroupsPackagesUiInfoLiveData(app, UsedCustomPermGroupNamesLiveData())
47     val additionaPermGroupsUiInfo =
48         PermGroupsPackagesUiInfoLiveData(
49             app,
50             if (Flags.declutteredPermissionManagerEnabled()) AdditionalPermGroupNamesLiveData(app)
51             else MutableLiveData<List<String>>(),
52         )
53 
54     /**
55      * Navigate to a Permission Apps fragment
56      *
57      * @param fragment The fragment we are navigating from
58      * @param args The args to pass to the new fragment
59      */
showPermissionAppsnull60     fun showPermissionApps(fragment: Fragment, args: Bundle) {
61         val groupName = args.getString(Intent.EXTRA_PERMISSION_GROUP_NAME)
62         if (groupName == Manifest.permission_group.NOTIFICATIONS) {
63             Utils.navigateToNotificationSettings(fragment.context!!)
64             return
65         }
66         if (Utils.isHealthPermissionUiEnabled() && groupName == HEALTH_PERMISSION_GROUP) {
67             Utils.navigateToHealthConnectSettings(fragment.context!!)
68             return
69         }
70         fragment.findNavController().navigateSafe(R.id.manage_to_perm_apps, args)
71     }
72 }
73 
74 /**
75  * Factory for a ManageCustomPermissionsViewModel
76  *
77  * @param app The current application of the fragment
78  */
79 class ManageCustomPermissionsViewModelFactory(private val app: Application) :
80     ViewModelProvider.Factory {
createnull81     override fun <T : ViewModel> create(modelClass: Class<T>): T {
82         @Suppress("UNCHECKED_CAST")
83         return ManageCustomPermissionsViewModel(app) as T
84     }
85 }
86 
87 /**
88  * A LiveData which tracks the names of Custom Permission Groups which are used by at least one
89  * package. This includes single-permission permission groups, as well as the Undefined permission
90  * group, and any other permission groups not defined by the system.
91  */
92 class UsedCustomPermGroupNamesLiveData : SmartUpdateMediatorLiveData<List<String>>() {
93 
94     init {
<lambda>null95         addSource(PermGroupsPackagesLiveData.get(customGroups = true)) { value = it.keys.toList() }
96     }
97 
onUpdatenull98     override fun onUpdate() {
99         /* No op override */
100     }
101 }
102 
103 /**
104  * A LiveData that is the union of LiveData UsedCustomPermGroupNamesLiveData and
105  * UnusedStandardPermGroupNamesLiveData.
106  *
107  * @param app The current application of the fragment
108  */
109 class AdditionalPermGroupNamesLiveData(private val app: Application) :
110     SmartUpdateMediatorLiveData<List<String>>() {
111 
112     val usedCustomGroupNames = UsedCustomPermGroupNamesLiveData()
113     val unusedStandardGroupNames = UnusedStandardPermGroupNamesLiveData(app)
114 
115     init {
<lambda>null116         addSource(usedCustomGroupNames) { update() }
<lambda>null117         addSource(unusedStandardGroupNames) { update() }
118     }
119 
combineGroupNamesnull120     private fun combineGroupNames(
121         groupNames1: List<String>?,
122         groupNames2: List<String>?,
123     ): List<String> {
124         return (groupNames1 ?: emptyList()) + (groupNames2 ?: emptyList())
125     }
126 
onUpdatenull127     override fun onUpdate() {
128         value = combineGroupNames(usedCustomGroupNames.value, unusedStandardGroupNames.value)
129     }
130 }
131