• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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 @file:JvmName("UserSensitiveFlagsUtils")
18 
19 package com.android.permissioncontroller.permission.utils
20 
21 import android.content.pm.PackageManager
22 import android.os.UserHandle
23 import android.util.Log
24 import com.android.permissioncontroller.PermissionControllerApplication
25 import com.android.permissioncontroller.permission.data.UserSensitivityLiveData
26 import com.android.permissioncontroller.permission.model.livedatatypes.UidSensitivityState
27 import com.android.permissioncontroller.permission.utils.Utils.FLAGS_ALWAYS_USER_SENSITIVE
28 import kotlinx.coroutines.GlobalScope
29 import kotlinx.coroutines.launch
30 import java.lang.IllegalStateException
31 
32 private const val LOG_TAG = "UserSensitiveFlagsUtils"
33 
34 /**
35  * Update the [PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED] and
36  * [PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED] for all apps of this user.
37  *
38  * @see UserSensitivityLiveData.loadDataAndPostValue
39  *
40  * @param user The user for whom packages will be updated
41  * @param callback A callback which will be executed when finished
42  */
updateUserSensitiveForUsernull43 fun updateUserSensitiveForUser(user: UserHandle, callback: Runnable) {
44     GlobalScope.launch(IPC) {
45         // a map of <uid, uid state>
46         val uidUserSensitivity = UserSensitivityLiveData[user].getInitializedValue()
47         if (uidUserSensitivity == null) {
48             callback.run()
49             throw IllegalStateException(
50                 "All uids sensitivity liveData should not be null if initialized")
51         }
52         updateUserSensitiveForUidsInternal(uidUserSensitivity, user, callback)
53     }
54 }
55 
updateUserSensitiveForUidsInternalnull56 private fun updateUserSensitiveForUidsInternal(
57     uidsUserSensitivity: Map<Int, UidSensitivityState>,
58     user: UserHandle,
59     callback: Runnable?
60 ) {
61     val userContext = Utils.getUserContext(PermissionControllerApplication.get(), user)
62     val pm = userContext.packageManager
63 
64     for ((uid, uidState) in uidsUserSensitivity) {
65             for (pkg in uidState.packages) {
66                 for (perm in pkg.requestedPermissions) {
67                     var flags = uidState.permStates[perm] ?: continue
68 
69                     try {
70                         val oldFlags = pm.getPermissionFlags(perm, pkg.packageName, user) and
71                             FLAGS_ALWAYS_USER_SENSITIVE
72                         if (flags != oldFlags) {
73                             pm.updatePermissionFlags(perm, pkg.packageName,
74                                 FLAGS_ALWAYS_USER_SENSITIVE, flags, user)
75                         }
76                     } catch (e: IllegalArgumentException) {
77                         if (e.message?.startsWith("Unknown permission: ") == false) {
78                             Log.e(LOG_TAG, "Unexpected exception while updating flags for " +
79                                 "${pkg.packageName} (uid $uid) permission $perm", e)
80                         } else {
81                             // Unknown permission - ignore
82                         }
83                     }
84                 }
85             }
86         }
87     callback?.run()
88 }
89 
90 /**
91  * [updateUserSensitiveForUser] for a single [uid]
92  *
93  * @param uid The uid to be updated
94  * @param callback A callback which will be executed when finished
95  */
96 @JvmOverloads
updateUserSensitiveForUidnull97 fun updateUserSensitiveForUid(uid: Int, callback: Runnable? = null) {
98     GlobalScope.launch(IPC) {
99         val uidSensitivityState = UserSensitivityLiveData[uid].getInitializedValue()
100         if (uidSensitivityState != null) {
101             updateUserSensitiveForUidsInternal(uidSensitivityState,
102                 UserHandle.getUserHandleForUid(uid), callback)
103         } else {
104             Log.e(LOG_TAG, "No packages associated with uid $uid, not updating flags")
105             callback?.run()
106         }
107     }
108 }
109