1 /*
<lambda>null2 * Copyright (C) 2020 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.utils
18
19 import android.app.Activity
20 import android.app.Application
21 import android.app.Service
22 import android.content.Context
23 import android.content.ContextWrapper
24 import android.content.pm.PackageManager
25 import android.os.Looper
26 import android.os.UserHandle
27 import kotlinx.coroutines.asCoroutineDispatcher
28 import java.util.concurrent.Executors
29
30 /**
31 * Gets an [Application] instance from a regular [Context]
32 */
33 val Context.application: Application get() = when (this) {
34 is Application -> this
35 is Activity -> application
36 is Service -> application
37 is ContextWrapper -> baseContext.application
38 else -> applicationContext as Application
39 }
40
41 /**
42 * The number of threads in the IPC thread pool. Set to the maximum number of binder threads allowed
43 * to an app by the Android System.
44 */
45 const val IPC_THREAD_POOL_COUNT = 8
46
47 /**
48 * A coroutine dispatcher with a fixed thread pool size, to be used for background tasks
49 */
50 val IPC = Executors.newFixedThreadPool(IPC_THREAD_POOL_COUNT).asCoroutineDispatcher()
51
52 /**
53 * Assert that an operation is running on main thread
54 */
ensureMainThreadnull55 fun ensureMainThread() = check(Looper.myLooper() == Looper.getMainLooper()) {
56 "Only meant to be used on the main thread"
57 }
58
59 /**
60 * A more readable version of [PackageManager.updatePermissionFlags]
61 */
PackageManagernull62 fun PackageManager.updatePermissionFlags(
63 permissionName: String,
64 packageName: String,
65 user: UserHandle,
66 vararg flags: Pair<Int, Boolean>
67 ) {
68 val mask = flags.fold(0, { mask, (flag, _) -> mask or flag })
69 val value = flags.fold(0, { mask, (flag, flagValue) -> if (flagValue) mask or flag else mask })
70 updatePermissionFlags(permissionName, packageName, mask, value, user)
71 }
72
73 /**
74 * @see UserHandle.getUid
75 */
getUidnull76 fun UserHandle.getUid(appId: Int): Int {
77 return identifier * 100000 + (appId % 100000)
78 }