• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2019 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.data
18 
19 import android.app.Application
20 import android.content.pm.PackageManager
21 import com.android.permissioncontroller.PermissionControllerApplication
22 
23 /**
24  * Serves as a single shared Permission Change Listener for all AppPermissionGroupLiveDatas.
25  *
26  */
27 object PermissionListenerMultiplexer : PackageManager.OnPermissionsChangedListener {
28 
29     private val app: Application = PermissionControllerApplication.get()
30     /**
31      * Map<UID, list of PermissionChangeCallbacks that wish to be informed when
32      * permissions are updated for that UID>
33      */
34     private val callbacks = mutableMapOf<Int, MutableList<PermissionChangeCallback>>()
35     private val pm = app.applicationContext.packageManager
36 
37     override fun onPermissionsChanged(uid: Int) {
38         callbacks[uid]?.toList()?.forEach { callback ->
39             callback.onPermissionChange()
40         }
41     }
42 
43     fun addOrReplaceCallback(oldUid: Int?, newUid: Int, callback: PermissionChangeCallback) {
44         if (oldUid != null) {
45             removeCallback(oldUid, callback)
46         }
47         addCallback(newUid, callback)
48     }
49 
50     fun addCallback(uid: Int, callback: PermissionChangeCallback) {
51         val wasEmpty = callbacks.isEmpty()
52 
53         callbacks.getOrPut(uid, { mutableListOf() }).add(callback)
54 
55         if (wasEmpty) {
56             pm.addOnPermissionsChangeListener(this)
57         }
58     }
59 
60     fun removeCallback(uid: Int, callback: PermissionChangeCallback) {
61         if (!callbacks.contains(uid)) {
62             return
63         }
64 
65         if (!callbacks[uid]!!.remove(callback)) {
66             return
67         }
68 
69         if (callbacks[uid]!!.isEmpty()) {
70             callbacks.remove(uid)
71         }
72 
73         if (callbacks.isEmpty()) {
74             pm.removeOnPermissionsChangeListener(this)
75         }
76     }
77 
78     interface PermissionChangeCallback {
79         fun onPermissionChange()
80     }
81 }