Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 706f9d13 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add NDK PermissionManager checkPermission"

parents bb75a481 b632bd57
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
/*
 * 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
+13 −0
Original line number Diff line number Diff line
@@ -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) {
+19 −0
Original line number Diff line number Diff line
@@ -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;
    }
};

// ------------------------------------------------------------------------------------
+2 −2
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ 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 unlinkToDeath(const sp<IBinder::DeathRecipient>& recipient);
+6 −1
Original line number Diff line number Diff line
@@ -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,
    };
};