diff options
-rw-r--r-- | include/android/permission_manager.h | 91 | ||||
-rw-r--r-- | libs/binder/ActivityManager.cpp | 13 | ||||
-rw-r--r-- | libs/binder/IActivityManager.cpp | 19 | ||||
-rw-r--r-- | libs/binder/include/binder/ActivityManager.h | 4 | ||||
-rw-r--r-- | libs/binder/include/binder/IActivityManager.h | 7 |
5 files changed, 131 insertions, 3 deletions
diff --git a/include/android/permission_manager.h b/include/android/permission_manager.h new file mode 100644 index 0000000000..7817126eec --- /dev/null +++ b/include/android/permission_manager.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 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. + */ + +#ifndef ANDROID_PERMISSION_MANAGER_H +#define ANDROID_PERMISSION_MANAGER_H + +#include <sys/cdefs.h> +#include <sys/types.h> + +__BEGIN_DECLS + +/** + * Permission check results. + * + * Introduced in API 31. + */ +enum { + /** + * This is returned by APermissionManager_checkPermission() + * if the permission has been granted to the given package. + */ + PERMISSION_MANAGER_PERMISSION_GRANTED = 0, + /** + * This is returned by APermissionManager_checkPermission() + * if the permission has not been granted to the given package. + */ + PERMISSION_MANAGER_PERMISSION_DENIED = -1, +}; + +/** + * Permission check return status values. + * + * Introduced in API 31. + */ +enum { + /** + * This is returned if the permission check completed without errors. + * The output result is valid and contains one of {PERMISSION_MANAGER_PERMISSION_GRANTED, + * PERMISSION_MANAGER_PERMISSION_DENIED}. + */ + PERMISSION_MANAGER_STATUS_OK = 0, + /** + * This is returned if the permission check encountered an unspecified error. + * The output result is unmodified. + */ + PERMISSION_MANAGER_STATUS_ERROR_UNKNOWN = -1, + /** + * This is returned if the permission check failed because the service is + * unavailable. The output result is unmodified. + */ + PERMISSION_MANAGER_STATUS_SERVICE_UNAVAILABLE = -2, +}; + +#if __ANDROID_API__ >= 31 + +/** + * Checks whether the package with the given pid/uid has been granted a permission. + * + * Note that the Java API of Context#checkPermission() is usually faster due to caching, + * thus is preferred over this API wherever possible. + * + * @param permission the permission to be checked. + * @param pid the process id of the package to be checked. + * @param uid the uid of the package to be checked. + * @param outResult output of the permission check result. + * + * @return error codes if any error happened during the check. + */ +int32_t APermissionManager_checkPermission(const char* permission, + pid_t pid, + uid_t uid, + int32_t* outResult) __INTRODUCED_IN(31); + +#endif // __ANDROID_API__ >= 31 + +__END_DECLS + +#endif // ANDROID_PERMISSION_MANAGER_H diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp index 5e4c98fc7a..727ea6024b 100644 --- a/libs/binder/ActivityManager.cpp +++ b/libs/binder/ActivityManager.cpp @@ -17,6 +17,7 @@ #include <mutex> #include <unistd.h> +#include <android/permission_manager.h> #include <binder/ActivityManager.h> #include <binder/Binder.h> #include <binder/IServiceManager.h> @@ -98,6 +99,18 @@ int32_t ActivityManager::getUidProcessState(const uid_t uid, const String16& cal return PROCESS_STATE_UNKNOWN; } +status_t ActivityManager::checkPermission(const String16& permission, + const pid_t pid, + const uid_t uid, + int32_t* outResult) { + sp<IActivityManager> service = getService(); + if (service != nullptr) { + return service->checkPermission(permission, pid, uid, outResult); + } + // ActivityManagerService appears dead. Return usual error code for dead service. + return DEAD_OBJECT; +} + status_t ActivityManager::linkToDeath(const sp<IBinder::DeathRecipient>& recipient) { sp<IActivityManager> service = getService(); if (service != nullptr) { diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp index 1eb5363ae2..e9f5aae347 100644 --- a/libs/binder/IActivityManager.cpp +++ b/libs/binder/IActivityManager.cpp @@ -17,9 +17,11 @@ #include <unistd.h> #include <fcntl.h> +#include <android/permission_manager.h> #include <binder/ActivityManager.h> #include <binder/IActivityManager.h> #include <binder/Parcel.h> +#include <utils/Errors.h> namespace android { @@ -104,6 +106,23 @@ public: } return reply.readInt32(); } + + virtual status_t checkPermission(const String16& permission, + const pid_t pid, + const uid_t uid, + int32_t* outResult) { + Parcel data, reply; + data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor()); + data.writeString16(permission); + data.writeInt32(pid); + data.writeInt32(uid); + status_t err = remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply); + if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { + return err; + } + *outResult = reply.readInt32(); + return NO_ERROR; + } }; // ------------------------------------------------------------------------------------ diff --git a/libs/binder/include/binder/ActivityManager.h b/libs/binder/include/binder/ActivityManager.h index 9108e31758..6796723388 100644 --- a/libs/binder/include/binder/ActivityManager.h +++ b/libs/binder/include/binder/ActivityManager.h @@ -77,9 +77,9 @@ public: void unregisterUidObserver(const sp<IUidObserver>& observer); bool isUidActive(const uid_t uid, const String16& callingPackage); int getUidProcessState(const uid_t uid, const String16& callingPackage); + status_t checkPermission(const String16& permission, const pid_t pid, const uid_t uid, int32_t* outResult); - - status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient); + status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient); status_t unlinkToDeath(const sp<IBinder::DeathRecipient>& recipient); private: diff --git a/libs/binder/include/binder/IActivityManager.h b/libs/binder/include/binder/IActivityManager.h index e0248f6624..4573347307 100644 --- a/libs/binder/include/binder/IActivityManager.h +++ b/libs/binder/include/binder/IActivityManager.h @@ -39,13 +39,18 @@ public: virtual void unregisterUidObserver(const sp<IUidObserver>& observer) = 0; virtual bool isUidActive(const uid_t uid, const String16& callingPackage) = 0; virtual int32_t getUidProcessState(const uid_t uid, const String16& callingPackage) = 0; + virtual status_t checkPermission(const String16& permission, + const pid_t pid, + const uid_t uid, + int32_t* outResult) = 0; enum { OPEN_CONTENT_URI_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, REGISTER_UID_OBSERVER_TRANSACTION, UNREGISTER_UID_OBSERVER_TRANSACTION, IS_UID_ACTIVE_TRANSACTION, - GET_UID_PROCESS_STATE_TRANSACTION + GET_UID_PROCESS_STATE_TRANSACTION, + CHECK_PERMISSION_TRANSACTION, }; }; |