Merge "Add FSI toggle to per-app notification settings" into udc-dev
This commit is contained in:
@@ -74,6 +74,7 @@ public class AppNotificationSettings extends NotificationSettings {
|
||||
mControllers = new ArrayList<>();
|
||||
mControllers.add(new HeaderPreferenceController(context, this));
|
||||
mControllers.add(new BlockPreferenceController(context, mDependentFieldListener, mBackend));
|
||||
mControllers.add(new FullScreenIntentPermissionPreferenceController(context, mBackend));
|
||||
mControllers.add(new BadgePreferenceController(context, mBackend));
|
||||
mControllers.add(new AllowSoundPreferenceController(
|
||||
context, mDependentFieldListener, mBackend));
|
||||
|
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.app
|
||||
|
||||
import android.Manifest.permission.USE_FULL_SCREEN_INTENT
|
||||
import android.app.AppOpsManager
|
||||
import android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT
|
||||
import android.content.AttributionSource
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET
|
||||
import android.content.pm.PackageManager.GET_PERMISSIONS
|
||||
import android.os.UserHandle
|
||||
import android.permission.PermissionManager
|
||||
import android.util.Log
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.Preference.OnPreferenceChangeListener
|
||||
import com.android.settings.notification.NotificationBackend
|
||||
import com.android.settingslib.RestrictedSwitchPreference
|
||||
|
||||
class FullScreenIntentPermissionPreferenceController(
|
||||
context: Context,
|
||||
backend: NotificationBackend
|
||||
) : NotificationPreferenceController(context, backend), OnPreferenceChangeListener {
|
||||
private val packageManager = mPm!!
|
||||
private val permissionManager = context.getSystemService(PermissionManager::class.java)!!
|
||||
private val appOpsManager = context.getSystemService(AppOpsManager::class.java)!!
|
||||
|
||||
private val packageName get() = mAppRow.pkg
|
||||
private val uid get() = mAppRow.uid
|
||||
private val userHandle get() = UserHandle.getUserHandleForUid(uid)
|
||||
|
||||
override fun getPreferenceKey() = KEY_FSI_PERMISSION
|
||||
|
||||
override fun isAvailable(): Boolean {
|
||||
val inAppWidePreferences = mChannelGroup == null && mChannel == null
|
||||
|
||||
if (!inAppWidePreferences) {
|
||||
Log.wtf(TAG, "Belongs only in app-wide notification preferences!")
|
||||
}
|
||||
|
||||
return super.isAvailable() && inAppWidePreferences && isPermissionRequested()
|
||||
}
|
||||
|
||||
override fun isIncludedInFilter() = false
|
||||
|
||||
override fun updateState(preference: Preference) {
|
||||
check(KEY_FSI_PERMISSION.equals(preference.key))
|
||||
check(preference is RestrictedSwitchPreference)
|
||||
|
||||
preference.setDisabledByAdmin(mAdmin)
|
||||
preference.isEnabled = !preference.isDisabledByAdmin
|
||||
preference.isChecked = isPermissionGranted()
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, value: Any): Boolean {
|
||||
check(KEY_FSI_PERMISSION.equals(preference.key))
|
||||
check(preference is RestrictedSwitchPreference)
|
||||
check(value is Boolean)
|
||||
|
||||
if (isPermissionGranted() != value) {
|
||||
setPermissionGranted(value)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isPermissionRequested(): Boolean {
|
||||
val packageInfo = packageManager.getPackageInfo(packageName, GET_PERMISSIONS)
|
||||
|
||||
for (requestedPermission in packageInfo.requestedPermissions) {
|
||||
if (USE_FULL_SCREEN_INTENT.equals(requestedPermission)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isPermissionGranted(): Boolean {
|
||||
val attributionSource = AttributionSource.Builder(uid).setPackageName(packageName).build()
|
||||
|
||||
val permissionResult =
|
||||
permissionManager.checkPermissionForPreflight(USE_FULL_SCREEN_INTENT, attributionSource)
|
||||
|
||||
return (permissionResult == PermissionManager.PERMISSION_GRANTED)
|
||||
}
|
||||
|
||||
private fun setPermissionGranted(allowed: Boolean) {
|
||||
val mode = if (allowed) AppOpsManager.MODE_ALLOWED else AppOpsManager.MODE_ERRORED
|
||||
appOpsManager.setUidMode(OP_USE_FULL_SCREEN_INTENT, uid, mode)
|
||||
packageManager.updatePermissionFlags(
|
||||
USE_FULL_SCREEN_INTENT,
|
||||
packageName,
|
||||
FLAG_PERMISSION_USER_SET,
|
||||
FLAG_PERMISSION_USER_SET,
|
||||
userHandle
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY_FSI_PERMISSION = "fsi_permission"
|
||||
const val TAG = "FsiPermPrefController"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user