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.app.Application
20 import android.os.Bundle
21 import androidx.fragment.app.Fragment
22 import androidx.lifecycle.AndroidViewModel
23 import androidx.lifecycle.Transformations
24 import androidx.lifecycle.ViewModel
25 import androidx.lifecycle.ViewModelProvider
26 import androidx.navigation.fragment.findNavController
27 import com.android.permissioncontroller.R
28 import com.android.permissioncontroller.permission.data.PermGroupsPackagesLiveData
29 import com.android.permissioncontroller.permission.data.PermGroupsPackagesUiInfoLiveData
30 import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData
31 import com.android.permissioncontroller.permission.data.StandardPermGroupNamesLiveData
32 import com.android.permissioncontroller.permission.data.UnusedAutoRevokedPackagesLiveData
33 import com.android.permissioncontroller.permission.utils.navigateSafe
34 
35 /**
36  * A ViewModel for the ManageStandardPermissionsFragment. Provides a LiveData which watches over all
37  * platform permission groups, and sends async updates when these groups have changes. It also
38  * provides a liveData which watches the custom permission groups of the system, and provides
39  * a list of group names.
40  * @param app The current application of the fragment
41  */
42 class ManageStandardPermissionsViewModel(
43     private val app: Application
44 ) : AndroidViewModel(app) {
45 
46     val uiDataLiveData = PermGroupsPackagesUiInfoLiveData(app,
47         StandardPermGroupNamesLiveData)
48     val numCustomPermGroups = NumCustomPermGroupsWithPackagesLiveData()
<lambda>null49     val numAutoRevoked = Transformations.map(UnusedAutoRevokedPackagesLiveData) {
50         it?.size ?: 0
51     }
52 
53     /**
54      * Navigate to the Custom Permissions screen
55      *
56      * @param fragment The fragment we are navigating from
57      * @param args The args to pass to the new fragment
58      */
showCustomPermissionsnull59     fun showCustomPermissions(fragment: Fragment, args: Bundle) {
60         fragment.findNavController().navigateSafe(R.id.standard_to_custom, args)
61     }
62 
63     /**
64      * Navigate to a Permission Apps fragment
65      *
66      * @param fragment The fragment we are navigating from
67      * @param args The args to pass to the new fragment
68      */
showPermissionAppsnull69     fun showPermissionApps(fragment: Fragment, args: Bundle) {
70         fragment.findNavController().navigateSafe(R.id.manage_to_perm_apps, args)
71     }
72 
showAutoRevokenull73     fun showAutoRevoke(fragment: Fragment, args: Bundle) {
74         fragment.findNavController().navigateSafe(R.id.manage_to_auto_revoke, args)
75     }
76 }
77 
78 /**
79  * Factory for a ManageStandardPermissionsViewModel
80  *
81  * @param app The current application of the fragment
82  */
83 class ManageStandardPermissionsViewModelFactory(
84     private val app: Application
85 ) : ViewModelProvider.Factory {
createnull86     override fun <T : ViewModel> create(modelClass: Class<T>): T {
87         @Suppress("UNCHECKED_CAST")
88         return ManageStandardPermissionsViewModel(app) as T
89     }
90 }
91 
92 /**
93  * A LiveData which tracks the number of custom permission groups that are used by at least one
94  * package
95  */
96 class NumCustomPermGroupsWithPackagesLiveData() :
97     SmartUpdateMediatorLiveData<Int>() {
98 
99     private val customPermGroupPackages = PermGroupsPackagesLiveData.get(customGroups = true)
100 
101     init {
<lambda>null102         addSource(customPermGroupPackages) {
103             updateIfActive()
104         }
105     }
106 
onUpdatenull107     override fun onUpdate() {
108         value = customPermGroupPackages.value?.size ?: 0
109     }
110 }