• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.settings.notification.app
18 
19 import android.Manifest.permission.USE_FULL_SCREEN_INTENT
20 import android.app.AppOpsManager
21 import android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT
22 import android.content.AttributionSource
23 import android.content.Context
24 import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET
25 import android.content.pm.PackageManager.GET_PERMISSIONS
26 import android.os.UserHandle
27 import android.permission.PermissionManager
28 import android.util.Log
29 import androidx.preference.Preference
30 import androidx.preference.Preference.OnPreferenceChangeListener
31 import com.android.settings.notification.NotificationBackend
32 import com.android.settingslib.RestrictedSwitchPreference
33 
34 class FullScreenIntentPermissionPreferenceController(
35     context: Context,
36     backend: NotificationBackend
37 ) : NotificationPreferenceController(context, backend), OnPreferenceChangeListener {
38     private val packageManager = mPm!!
39     private val permissionManager = context.getSystemService(PermissionManager::class.java)!!
40     private val appOpsManager = context.getSystemService(AppOpsManager::class.java)!!
41 
42     private val packageName get() = mAppRow.pkg
43     private val uid get() = mAppRow.uid
44     private val userHandle get() = UserHandle.getUserHandleForUid(uid)
45 
getPreferenceKeynull46     override fun getPreferenceKey() = KEY_FSI_PERMISSION
47 
48     override fun isAvailable(): Boolean {
49         val inAppWidePreferences = mChannelGroup == null && mChannel == null
50 
51         if (!inAppWidePreferences) {
52             Log.wtf(TAG, "Belongs only in app-wide notification preferences!")
53         }
54 
55         return super.isAvailable() && inAppWidePreferences && isPermissionRequested()
56     }
57 
isIncludedInFilternull58     override fun isIncludedInFilter() = false
59 
60     override fun updateState(preference: Preference) {
61         check(KEY_FSI_PERMISSION.equals(preference.key))
62         check(preference is RestrictedSwitchPreference)
63 
64         preference.setDisabledByAdmin(mAdmin)
65         preference.isEnabled = !preference.isDisabledByAdmin
66         preference.isChecked = isPermissionGranted()
67     }
68 
onPreferenceChangenull69     override fun onPreferenceChange(preference: Preference, value: Any): Boolean {
70         check(KEY_FSI_PERMISSION.equals(preference.key))
71         check(preference is RestrictedSwitchPreference)
72         check(value is Boolean)
73 
74         if (isPermissionGranted() != value) {
75             setPermissionGranted(value)
76         }
77 
78         return true
79     }
80 
isPermissionRequestednull81     private fun isPermissionRequested(): Boolean {
82         val packageInfo = packageManager.getPackageInfo(packageName, GET_PERMISSIONS)
83 
84         for (requestedPermission in packageInfo.requestedPermissions) {
85             if (USE_FULL_SCREEN_INTENT.equals(requestedPermission)) {
86                 return true
87             }
88         }
89 
90         return false
91     }
92 
isPermissionGrantednull93     private fun isPermissionGranted(): Boolean {
94         val attributionSource = AttributionSource.Builder(uid).setPackageName(packageName).build()
95 
96         val permissionResult =
97             permissionManager.checkPermissionForPreflight(USE_FULL_SCREEN_INTENT, attributionSource)
98 
99         return (permissionResult == PermissionManager.PERMISSION_GRANTED)
100     }
101 
setPermissionGrantednull102     private fun setPermissionGranted(allowed: Boolean) {
103         val mode = if (allowed) AppOpsManager.MODE_ALLOWED else AppOpsManager.MODE_ERRORED
104         appOpsManager.setUidMode(OP_USE_FULL_SCREEN_INTENT, uid, mode)
105         packageManager.updatePermissionFlags(
106             USE_FULL_SCREEN_INTENT,
107             packageName,
108             FLAG_PERMISSION_USER_SET,
109             FLAG_PERMISSION_USER_SET,
110             userHandle
111         )
112     }
113 
114     companion object {
115         const val KEY_FSI_PERMISSION = "fsi_permission"
116         const val TAG = "FsiPermPrefController"
117     }
118 }