diff options
| -rw-r--r-- | packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt | 13 | ||||
| -rw-r--r-- | packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/AppOpApiPermissionChecker.kt | 46 |
2 files changed, 59 insertions, 0 deletions
diff --git a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt index 6d746e020243..33f1c3d11fa1 100644 --- a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt +++ b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt @@ -17,6 +17,7 @@ package com.android.settingslib.ipc import android.app.Application +import android.content.pm.PackageManager.PERMISSION_GRANTED import android.os.Bundle /** @@ -77,8 +78,20 @@ fun interface ApiPermissionChecker<R> { companion object { private val ALWAYS_ALLOW = ApiPermissionChecker<Any> { _, _, _, _ -> true } + /** Returns [ApiPermissionChecker] that allows all the request. */ @Suppress("UNCHECKED_CAST") fun <T> alwaysAllow(): ApiPermissionChecker<T> = ALWAYS_ALLOW as ApiPermissionChecker<T> + + /** + * Returns [ApiPermissionChecker] that checks if calling app has given [permission]. + * + * Use [AppOpApiPermissionChecker] if the [permission] is app-op. + */ + fun <T> of(permission: String) = + ApiPermissionChecker<T> { application, callingPid, callingUid, _ -> + application.checkPermission(permission, callingPid, callingUid) == + PERMISSION_GRANTED + } } } diff --git a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/AppOpApiPermissionChecker.kt b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/AppOpApiPermissionChecker.kt new file mode 100644 index 000000000000..4509c1e30305 --- /dev/null +++ b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/AppOpApiPermissionChecker.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2025 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.settingslib.ipc + +import android.app.AppOpsManager +import android.app.Application +import android.content.Context +import android.content.pm.PackageManager + +/** [ApiPermissionChecker] that checks if calling app has given app-op permission. */ +class AppOpApiPermissionChecker<T>(private val op: Int, private val permission: String) : + ApiPermissionChecker<T> { + + @Suppress("DEPRECATION") + override fun hasPermission( + application: Application, + callingPid: Int, + callingUid: Int, + request: T, + ): Boolean { + val appOpsManager = + application.getSystemService(Context.APP_OPS_SERVICE) as? AppOpsManager ?: return false + val pkg = application.packageManager.getNameForUid(callingUid) ?: return false + return when (appOpsManager.noteOp(op, callingUid, pkg)) { + AppOpsManager.MODE_ALLOWED -> true + AppOpsManager.MODE_DEFAULT -> + application.checkPermission(permission, callingPid, callingUid) == + PackageManager.PERMISSION_GRANTED + else -> false + } + } +} |