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

Commit f63651ec authored by Atneya Nair's avatar Atneya Nair Committed by Android (Google) Code Review
Browse files

Merge "Add permission caching to PermissionController" into main

parents 61189a17 c23be504
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.media.permission;

import com.android.media.permission.PermissionEnum;
import com.android.media.permission.UidPackageState;

/**
@@ -33,4 +34,13 @@ interface INativePermissionController {
     * If the list is empty, the package no longer exists.
     */
    void updatePackagesForUid(in UidPackageState newPackageState);
    /**
     * Populate or replace the list of uids which holds a particular permission.
     * Runtime permissions will need additional checks, and should not use the cache as-is.
     * Not virtual device aware.
     * Is is possible for updates to the permission state to be delayed during high traffic.
     * @param perm - Enum representing the permission for which holders are being supplied
     * @param uids - Uids (not app-ids) which hold the permission. Should be sorted
     */
    void populatePermissionState(in PermissionEnum perm, in int[] uids);
}
+31 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.media.permission;

/**
 * Enumerates permissions which are tracked/pushed by NativePermissionController
 * {@hide}
 */
enum PermissionEnum {
    MODIFY_AUDIO_ROUTING = 0,
    MODIFY_PHONE_STATE = 1,
    CALL_AUDIO_INTERCEPTION = 2,
    // This is a runtime + WIU permission, which means data delivery should be protected by AppOps
    // We query the controller only for early fails/hard errors
    RECORD_AUDIO = 3,
    ENUM_SIZE = 4, // Not for actual usage
}
+24 −0
Original line number Diff line number Diff line
@@ -88,6 +88,19 @@ Status NativePermissionController::updatePackagesForUid(const UidPackageState& n
    return Status::ok();
}

Status NativePermissionController::populatePermissionState(PermissionEnum perm,
                                                           const std::vector<int>& uids) {
    if (perm >= PermissionEnum::ENUM_SIZE || static_cast<int>(perm) < 0) {
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
    }
    std::lock_guard l{m_};
    auto& cursor = permission_map_[static_cast<size_t>(perm)];
    cursor = std::vector<uid_t>{uids.begin(), uids.end()};
    // should be sorted
    std::sort(cursor.begin(), cursor.end());
    return Status::ok();
}

// -- End Binder methods

Result<std::vector<std::string>> NativePermissionController::getPackagesForUid(uid_t uid) const {
@@ -120,4 +133,15 @@ Result<bool> NativePermissionController::validateUidPackagePair(
           (std::find(cursor->second.begin(), cursor->second.end(), packageName) !=
            cursor->second.end());
}

Result<bool> NativePermissionController::checkPermission(PermissionEnum perm, uid_t uid) const {
    std::lock_guard l{m_};
    const auto& uids = permission_map_[static_cast<size_t>(perm)];
    if (!uids.empty()) {
        return std::binary_search(uids.begin(), uids.end(), uid);
    } else {
        return unexpected{::android::NO_INIT};
    }
}

}  // namespace com::android::media::permission
+6 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <optional>
#include <vector>

#include <com/android/media/permission/PermissionEnum.h>
#include <error/Result.h>

namespace com::android::media::permission {
@@ -38,6 +39,11 @@ class IPermissionProvider {
    // Fails if the provider does not know about the app-id.
    virtual ::android::error::Result<bool> validateUidPackagePair(
            uid_t uid, const std::string& packageName) const = 0;

    // True iff the uid holds the permission (user aware).
    // Fails with NO_INIT if cache hasn't been populated.
    virtual ::android::error::Result<bool> checkPermission(PermissionEnum permission,
                                                           uid_t uid) const = 0;
    virtual ~IPermissionProvider() = default;
};
}  // namespace com::android::media::permission
+6 −0
Original line number Diff line number Diff line
@@ -33,16 +33,22 @@ class NativePermissionController : public BnNativePermissionController, public I
  public:
    Status populatePackagesForUids(const std::vector<UidPackageState>& initialPackageStates) final;
    Status updatePackagesForUid(const UidPackageState& newPackageState) final;
    Status populatePermissionState(PermissionEnum permission, const std::vector<int>& uids) final;
    // end binder methods

    ::android::error::Result<std::vector<std::string>> getPackagesForUid(uid_t uid) const final;
    ::android::error::Result<bool> validateUidPackagePair(
            uid_t uid, const std::string& packageName) const final;
    ::android::error::Result<bool> checkPermission(PermissionEnum permission,
                                                   uid_t uid) const final;

  private:
    mutable std::mutex m_;
    // map of app_ids to the set of packages names which could run in them (should be 1)
    std::unordered_map<uid_t, std::vector<std::string>> package_map_ GUARDED_BY(m_);
    bool is_package_populated_ GUARDED_BY(m_);
    // (logical) map of PermissionEnum to list of uids (not appid) which hold the perm
    std::array<std::vector<uid_t>, static_cast<size_t>(PermissionEnum::ENUM_SIZE)> permission_map_
            GUARDED_BY(m_);
};
}  // namespace com::android::media::permission
Loading