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.map
27 import androidx.navigation.fragment.findNavController
28 import com.android.permissioncontroller.R
29 import com.android.permissioncontroller.permission.data.PermGroupsPackagesLiveData
30 import com.android.permissioncontroller.permission.data.PermGroupsPackagesUiInfoLiveData
31 import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData
32 import com.android.permissioncontroller.permission.data.StandardPermGroupNamesLiveData
33 import com.android.permissioncontroller.permission.data.unusedAutoRevokePackagesLiveData
34 import com.android.permissioncontroller.permission.utils.Utils
35 import com.android.permissioncontroller.permission.utils.navigateSafe
36 
37 /**
38  * A ViewModel for the ManageStandardPermissionsFragment. Provides a LiveData which watches over all
39  * platform permission groups, and sends async updates when these groups have changes. It also
40  * provides a liveData which watches the custom permission groups of the system, and provides a list
41  * of group names.
42  *
43  * @param app The current application of the fragment
44  */
45 class ManageStandardPermissionsViewModel(private val app: Application) : AndroidViewModel(app) {
46 
47     val uiDataLiveData = PermGroupsPackagesUiInfoLiveData(app, StandardPermGroupNamesLiveData)
48     val numCustomPermGroups = NumCustomPermGroupsWithPackagesLiveData()
<lambda>null49     val numAutoRevoked = unusedAutoRevokePackagesLiveData.map { it?.size ?: 0 }
50 
51     /**
52      * Navigate to the Custom Permissions screen
53      *
54      * @param fragment The fragment we are navigating from
55      * @param args The args to pass to the new fragment
56      */
showCustomPermissionsnull57     fun showCustomPermissions(fragment: Fragment, args: Bundle) {
58         fragment.findNavController().navigateSafe(R.id.standard_to_custom, args)
59     }
60 
61     /**
62      * Navigate to a Permission Apps fragment
63      *
64      * @param fragment The fragment we are navigating from
65      * @param args The args to pass to the new fragment
66      */
showPermissionAppsnull67     fun showPermissionApps(fragment: Fragment, args: Bundle) {
68         val groupName = args.getString(Intent.EXTRA_PERMISSION_GROUP_NAME)
69         if (groupName == Manifest.permission_group.NOTIFICATIONS) {
70             Utils.navigateToNotificationSettings(fragment.context!!)
71             return
72         }
73         if (Utils.isHealthPermissionUiEnabled() && groupName == HEALTH_PERMISSION_GROUP) {
74             Utils.navigateToHealthConnectSettings(fragment.context!!)
75             return
76         }
77         fragment.findNavController().navigateSafe(R.id.manage_to_perm_apps, args)
78     }
79 
showAutoRevokenull80     fun showAutoRevoke(fragment: Fragment, args: Bundle) {
81         fragment.findNavController().navigateSafe(R.id.manage_to_auto_revoke, args)
82     }
83 }
84 
85 /**
86  * A LiveData which tracks the number of custom permission groups that are used by at least one
87  * package
88  */
89 class NumCustomPermGroupsWithPackagesLiveData() : SmartUpdateMediatorLiveData<Int>() {
90 
91     private val customPermGroupPackages = PermGroupsPackagesLiveData.get(customGroups = true)
92 
93     init {
<lambda>null94         addSource(customPermGroupPackages) { update() }
95     }
96 
onUpdatenull97     override fun onUpdate() {
98         value = customPermGroupPackages.value?.size ?: 0
99     }
100 }
101