1 /* <lambda>null2 * Copyright (C) 2024 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.data.repository.v31 18 19 import android.app.AppOpsManager 20 import android.content.pm.PackageManager 21 import com.android.modules.utils.build.SdkLevel 22 import com.android.permissioncontroller.permission.data.PackageBroadcastReceiver 23 24 class PermissionChangeListener( 25 private val packageManager: PackageManager, 26 private val callback: () -> Unit 27 ) : PackageManager.OnPermissionsChangedListener { 28 fun register() { 29 packageManager.addOnPermissionsChangeListener(this) 30 } 31 32 fun unregister() { 33 packageManager.removeOnPermissionsChangeListener(this) 34 } 35 36 override fun onPermissionsChanged(uid: Int) { 37 callback() 38 } 39 } 40 41 class PackageChangeListener(private val callback: () -> Unit) : 42 PackageBroadcastReceiver.PackageBroadcastListener { 43 registernull44 fun register() { 45 PackageBroadcastReceiver.addAllCallback(this) 46 } 47 unregisternull48 fun unregister() { 49 PackageBroadcastReceiver.removeAllCallback(this) 50 } 51 onPackageUpdatenull52 override fun onPackageUpdate(packageName: String) { 53 callback() 54 } 55 } 56 57 // Suppress OnOpNotedListener, it was introduced in Q but became System API in U. 58 @SuppressWarnings("NewApi") 59 class AppOpChangeListener( 60 private val opNames: Set<String>, 61 private val appOpsManager: AppOpsManager, 62 private val callback: () -> Unit 63 ) : 64 AppOpsManager.OnOpChangedListener, 65 AppOpsManager.OnOpNotedListener, 66 AppOpsManager.OnOpActiveChangedListener { 67 registernull68 fun register() { 69 opNames.forEach { opName -> 70 // TODO(b/262035952): We watch each active op individually as 71 // startWatchingActive only registers the callback if all ops are valid. 72 // Fix this behavior so if one op is invalid it doesn't affect the other ops. 73 try { 74 appOpsManager.startWatchingActive(arrayOf(opName), { it.run() }, this) 75 } catch (ignored: IllegalArgumentException) { 76 // Older builds may not support all requested app ops. 77 } 78 79 try { 80 appOpsManager.startWatchingMode(opName, /* all packages */ null, this) 81 } catch (ignored: IllegalArgumentException) { 82 // Older builds may not support all requested app ops. 83 } 84 85 if (SdkLevel.isAtLeastU()) { 86 try { 87 appOpsManager.startWatchingNoted(arrayOf(opName), this) 88 } catch (ignored: IllegalArgumentException) { 89 // Older builds may not support all requested app ops. 90 } 91 } 92 } 93 } 94 unregisternull95 fun unregister() { 96 appOpsManager.stopWatchingActive(this) 97 appOpsManager.stopWatchingMode(this) 98 if (SdkLevel.isAtLeastU()) { 99 appOpsManager.stopWatchingNoted(this) 100 } 101 } 102 onOpChangednull103 override fun onOpChanged(op: String?, packageName: String?) { 104 callback() 105 } 106 onOpNotednull107 override fun onOpNoted( 108 op: String, 109 uid: Int, 110 packageName: String, 111 attributionTag: String?, 112 flags: Int, 113 result: Int 114 ) { 115 callback() 116 } 117 onOpActiveChangednull118 override fun onOpActiveChanged(op: String, uid: Int, packageName: String, active: Boolean) { 119 callback() 120 } 121 } 122