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

Commit a23a744d authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12985272 from f9f248a4 to 25Q2-release

Change-Id: I20726bf0cf61632cd7e66fdaf4405f4d441e7343
parents 9ac0237c f9f248a4
Loading
Loading
Loading
Loading
+49 −16
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#define LOG_TAG "AudioTestUtils"

#include <android-base/file.h>
#include <android/content/pm/IPackageManagerNative.h>
#include <binder/IServiceManager.h>
#include <system/audio_config.h>
#include <utils/Log.h>

@@ -644,6 +646,28 @@ uint32_t AudioCapture::waitAndGetReceivedCbMarkerCount() const {
    return mReceivedCbMarkerCount.value_or(0);
}

status_t isAutomotivePlatform(bool* isAutomotive) {
    const sp<IServiceManager> sm = defaultServiceManager();
    if (sm == nullptr) {
        ALOGE("%s: failed to retrieve defaultServiceManager", __func__);
        return NO_INIT;
    }
    sp<IBinder> binder = sm->checkService(String16{"package_native"});
    if (binder == nullptr) {
        ALOGE("%s: failed to retrieve native package manager", __func__);
        return NO_INIT;
    }
    *isAutomotive = false;
    const auto pm = interface_cast<content::pm::IPackageManagerNative>(binder);
    if (pm != nullptr) {
        const auto status =
                pm->hasSystemFeature(String16("android.hardware.type.automotive"), 0, isAutomotive);
        return status.isOk() ? OK : status.transactionError();
    }
    ALOGE("%s: failed to cast to IPackageManagerNative", __func__);
    return NO_INIT;
}

status_t listAudioPorts(std::vector<audio_port_v7>& portsVec) {
    int attempts = 5;
    status_t status;
@@ -673,34 +697,43 @@ status_t listAudioPorts(std::vector<audio_port_v7>& portsVec) {
    return status;
}

status_t getPortById(const audio_port_handle_t portId, audio_port_v7& port) {
namespace {

using PortPredicate = std::function<bool(const struct audio_port_v7& port)>;
status_t getPort(PortPredicate pred, audio_port_v7& port) {
    std::vector<struct audio_port_v7> ports;
    status_t status = listAudioPorts(ports);
    if (status != OK) return status;
    for (auto i = 0; i < ports.size(); i++) {
        if (ports[i].id == portId) {
            port = ports[i];
    for (const auto& p : ports) {
        if (pred(p)) {
            port = p;
            return OK;
        }
    }
    return BAD_VALUE;
}

}  // namespace

status_t getAnyPort(audio_port_role_t role, audio_port_type_t type, audio_port_v7& port) {
    return getPort([&](const struct audio_port_v7& p) { return p.role == role && p.type == type; },
                   port);
}

status_t getPortById(const audio_port_handle_t portId, audio_port_v7& port) {
    return getPort([&](const struct audio_port_v7& p) { return p.id == portId; }, port);
}

status_t getPortByAttributes(audio_port_role_t role, audio_port_type_t type,
                             audio_devices_t deviceType, const std::string& address,
                             audio_port_v7& port) {
    std::vector<struct audio_port_v7> ports;
    status_t status = listAudioPorts(ports);
    if (status != OK) return status;
    for (auto i = 0; i < ports.size(); i++) {
        if (ports[i].role == role && ports[i].type == type &&
            ports[i].ext.device.type == deviceType &&
            !strncmp(ports[i].ext.device.address, address.c_str(), AUDIO_DEVICE_MAX_ADDRESS_LEN)) {
            port = ports[i];
            return OK;
        }
    }
    return BAD_VALUE;
    return getPort(
            [&](const struct audio_port_v7& p) {
                return p.role == role && p.type == type && p.ext.device.type == deviceType &&
                       !strncmp(p.ext.device.address, address.c_str(),
                                AUDIO_DEVICE_MAX_ADDRESS_LEN);
            },
            port);
}

status_t listAudioPatches(std::vector<struct audio_patch>& patchesVec) {
+2 −0
Original line number Diff line number Diff line
@@ -45,8 +45,10 @@ struct Route {
    std::string sink;
};

status_t isAutomotivePlatform(bool* isAutomotive);
status_t listAudioPorts(std::vector<audio_port_v7>& portsVec);
status_t listAudioPatches(std::vector<struct audio_patch>& patchesVec);
status_t getAnyPort(audio_port_role_t role, audio_port_type_t type, audio_port_v7& port);
status_t getPortByAttributes(audio_port_role_t role, audio_port_type_t type,
                             audio_devices_t deviceType, const std::string& address,
                             audio_port_v7& port);
+10 −0
Original line number Diff line number Diff line
@@ -98,6 +98,11 @@ public:
};

TEST_P(AudioTrackTest, DefaultRoutingTest) {
    bool isAutomotive;
    ASSERT_EQ(OK, isAutomotivePlatform(&isAutomotive));
    if (isAutomotive) {
        GTEST_SKIP() << "auto uses its own policy for routing";
    }
    audio_port_v7 port;
    if (OK != getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
                                  AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port)) {
@@ -154,6 +159,11 @@ INSTANTIATE_TEST_SUITE_P(
class AudioRoutingTest : public ::testing::Test {
  public:
    void SetUp() override {
        bool isAutomotive;
        ASSERT_EQ(OK, isAutomotivePlatform(&isAutomotive));
        if (isAutomotive) {
            GTEST_SKIP() << "auto uses its own policy for routing";
        }
        audio_port_v7 port;
        if (OK != getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
                                      AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port)) {
+16 −10
Original line number Diff line number Diff line
@@ -562,12 +562,15 @@ TEST_F(AudioSystemTest, UidDeviceAffinities) {
    AudioDeviceTypeAddrVector inputDevices = {inputDevice};
    EXPECT_EQ(BAD_VALUE, AudioSystem::setUidDeviceAffinities(uid, inputDevices));

    audio_port_v7 port;
    if (OK == getAnyPort(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, port)) {
        // Test valid device for example audio_is_output_device
    AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
        AudioDeviceTypeAddr outputDevice(port.ext.device.type, port.ext.device.address);
        AudioDeviceTypeAddrVector outputDevices = {outputDevice};
        EXPECT_EQ(NO_ERROR, AudioSystem::setUidDeviceAffinities(uid, outputDevices));
        EXPECT_EQ(NO_ERROR, AudioSystem::removeUidDeviceAffinities(uid));
    }
}

TEST_F(AudioSystemTest, UserIdDeviceAffinities) {
    int userId = 200;
@@ -577,12 +580,15 @@ TEST_F(AudioSystemTest, UserIdDeviceAffinities) {
    AudioDeviceTypeAddrVector inputDevices = {inputDevice};
    EXPECT_EQ(BAD_VALUE, AudioSystem::setUserIdDeviceAffinities(userId, inputDevices));

    // Test valid device for ezample audio_is_output_device
    AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
    audio_port_v7 port;
    if (OK == getAnyPort(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, port)) {
        // Test valid device for example audio_is_output_device
        AudioDeviceTypeAddr outputDevice(port.ext.device.type, port.ext.device.address);
        AudioDeviceTypeAddrVector outputDevices = {outputDevice};
        EXPECT_EQ(NO_ERROR, AudioSystem::setUserIdDeviceAffinities(userId, outputDevices));
        EXPECT_EQ(NO_ERROR, AudioSystem::removeUserIdDeviceAffinities(userId));
    }
}

namespace {

+139 −24
Original line number Diff line number Diff line
@@ -3221,6 +3221,56 @@ void CameraService::notifyMonitoredUids(const std::unordered_set<uid_t> &notifyU
    }
}

void CameraService::updateSharedClientAccessPriorities(std::vector<int> sharedClientPids) {
    Mutex::Autolock lock(mServiceLock);
    if (!flags::camera_multi_client() || sharedClientPids.empty()) {
        return;
    }
    std::vector<int> scores(sharedClientPids.size());
    std::vector<int> states(sharedClientPids.size());
    status_t err = ProcessInfoService::getProcessStatesScoresFromPids(sharedClientPids.size(),
                &sharedClientPids[0], /*out*/&states[0], /*out*/&scores[0]);
    if (err != OK) {
        return;
    }
    for (size_t i = 0; i < sharedClientPids.size(); i++) {
        auto clientDescriptorPtr = mActiveClientManager.getSharedClient(sharedClientPids[i]);
        if (clientDescriptorPtr == nullptr) {
            continue;
        }
        const auto& clientPriority = clientDescriptorPtr->getPriority();
        int score = clientPriority.getScore();
        int state = clientPriority.getState();
        if ((score != scores[i])  || (state != states[i])){
            clientDescriptorPtr->setPriority(resource_policy::ClientPriority(scores[i], states[i],
                    false, 0));
            notifySharedClientPrioritiesChanged(clientDescriptorPtr->getKey());
        }
    }
}

void CameraService::notifySharedClientPrioritiesChanged(const std::string& cameraId) {
    if (!flags::camera_multi_client()) {
        return;
    }
    auto primaryClientDesc = mActiveClientManager.getPrimaryClient(cameraId);
    if (primaryClientDesc == nullptr) {
        return;
    }
    auto primaryClient = primaryClientDesc->getValue();
    if (primaryClient == nullptr) {
        return;
    }
    auto highestPriorityClient = mActiveClientManager.getHighestPrioritySharedClient(cameraId);
    if (highestPriorityClient == primaryClient) {
        return;
    }
    highestPriorityClient->setPrimaryClient(true);
    highestPriorityClient->notifyClientSharedAccessPriorityChanged(true);
    primaryClient->setPrimaryClient(false);
    primaryClient->notifyClientSharedAccessPriorityChanged(false);
}

Status CameraService::notifyDeviceStateChange(int64_t newState) {
    const int pid = getCallingPid();
    const int selfPid = getpid();
@@ -4357,6 +4407,10 @@ status_t CameraService::BasicClient::notifyCameraOpening() {

    sCameraService->mUidPolicy->registerMonitorUid(getClientUid(), /*openCamera*/ true);

    if (flags::camera_multi_client() && mSharedMode) {
        sCameraService->mUidPolicy->addSharedClientPid(getClientUid(), getClientCallingPid());
    }

    // Notify listeners of camera open/close status
    sCameraService->updateOpenCloseStatus(mCameraIdStr, true /*open*/, getPackageName(),
            mSharedMode);
@@ -4515,6 +4569,10 @@ status_t CameraService::BasicClient::notifyCameraClosing() {

    sCameraService->mUidPolicy->unregisterMonitorUid(getClientUid(), /*closeCamera*/ true);

    if (flags::camera_multi_client() && mSharedMode) {
        sCameraService->mUidPolicy->removeSharedClientPid(getClientUid(), getClientCallingPid());
    }

    // Notify listeners of camera open/close status
    sCameraService->updateOpenCloseStatus(mCameraIdStr, false /*open*/, getPackageName(),
            mSharedMode);
@@ -4783,21 +4841,35 @@ void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
void CameraService::UidPolicy::onUidStateChanged(uid_t uid, int32_t procState,
        int64_t procStateSeq __unused, int32_t capability __unused) {
    bool procStateChange = false;
    std::vector<int> sharedPids;
    {
        Mutex::Autolock _l(mUidLock);
        if (mMonitoredUids.find(uid) != mMonitoredUids.end() &&
                mMonitoredUids[uid].procState != procState) {
        if (mMonitoredUids.find(uid) != mMonitoredUids.end()) {
            if (mMonitoredUids[uid].procState != procState) {
                mMonitoredUids[uid].procState = procState;
                procStateChange = true;
            }
            if (flags::camera_multi_client()) {
                std::unordered_set<int> sharedClientPids = mMonitoredUids[uid].sharedClientPids;
                if (!sharedClientPids.empty()) {
                  sharedPids.assign(sharedClientPids.begin(), sharedClientPids.end());
                }
            }
        }
    }

    if (procStateChange) {
    sp<CameraService> service = mService.promote();
    if (procStateChange) {
        if (service != nullptr) {
            service->notifyMonitoredUids();
        }
    }

    if (flags::camera_multi_client() && !sharedPids.empty()) {
        if (service != nullptr) {
            service->updateSharedClientAccessPriorities(sharedPids);
        }
    }
}

/**
@@ -4810,6 +4882,7 @@ void CameraService::UidPolicy::onUidStateChanged(uid_t uid, int32_t procState,
 */
void CameraService::UidPolicy::onUidProcAdjChanged(uid_t uid, int32_t adj) {
    std::unordered_set<uid_t> notifyUidSet;
    std::vector<int> sharedPids;
    {
        Mutex::Autolock _l(mUidLock);
        auto it = mMonitoredUids.find(uid);
@@ -4833,15 +4906,28 @@ void CameraService::UidPolicy::onUidProcAdjChanged(uid_t uid, int32_t adj) {
                }
            }
            it->second.procAdj = adj;
            if (flags::camera_multi_client()) {
                std::unordered_set<int> sharedClientPids = it->second.sharedClientPids;
                if (!sharedClientPids.empty()) {
                    sharedPids.assign(sharedClientPids.begin(), sharedClientPids.end());
                }
            }
        }
    }

    if (notifyUidSet.size() > 0) {
    sp<CameraService> service = mService.promote();

    if (notifyUidSet.size() > 0) {
        if (service != nullptr) {
            service->notifyMonitoredUids(notifyUidSet);
        }
    }

    if (flags::camera_multi_client() && !sharedPids.empty()) {
        if (service != nullptr) {
            service->updateSharedClientAccessPriorities(sharedPids);
        }
    }
}

/**
@@ -4975,6 +5061,20 @@ void CameraService::UidPolicy::removeOverrideUid(uid_t uid, const std::string &c
    updateOverrideUid(uid, callingPackage, false, false);
}

void CameraService::UidPolicy::addSharedClientPid(uid_t uid, int pid) {
    Mutex::Autolock _l(mUidLock);
    if (mMonitoredUids.find(uid) != mMonitoredUids.end()) {
        mMonitoredUids[uid].sharedClientPids.insert(pid);
    }
}

void CameraService::UidPolicy::removeSharedClientPid(uid_t uid, int pid) {
    Mutex::Autolock _l(mUidLock);
    if (mMonitoredUids.find(uid) != mMonitoredUids.end()) {
        mMonitoredUids[uid].sharedClientPids.erase(pid);
    }
}

void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
    Mutex::Autolock _l(mUidLock);
    ALOGV("UidPolicy: ActivityManager has died");
@@ -5281,32 +5381,47 @@ sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClie
    return descriptor->getValue();
}

void CameraService::CameraClientManager::remove(const CameraService::DescriptorPtr& value) {
    ClientManager::remove(value);
sp<CameraService::BasicClient> CameraService::CameraClientManager::getHighestPrioritySharedClient(
        const std::string& id) const {
    if (!flags::camera_multi_client()) {
        return;
        return sp<BasicClient>{nullptr};
    }
    auto clientToRemove = value->getValue();
    if ((clientToRemove.get() != nullptr) && clientToRemove->mSharedMode) {
      bool primaryClient = false;
      status_t ret = clientToRemove->isPrimaryClient(&primaryClient);
      if ((ret == OK) && primaryClient) {
            // Primary client is being removed. Find the next higher priority
            // client to become primary client.
            auto clientDescriptor = get(value->getKey());
    auto clientDescriptor = get(id);
    if (clientDescriptor == nullptr) {
        ALOGV("CameraService::CameraClientManager::no other clients are using same camera");
                return;
        return sp<BasicClient>{nullptr};
    }
    if (!clientDescriptor->getSharedMode()) {
        return sp<BasicClient>{nullptr};
    }
    resource_policy::ClientPriority highestPriority = clientDescriptor->getPriority();
    sp<BasicClient> highestPriorityClient = clientDescriptor->getValue();
            if (highestPriorityClient.get() != nullptr) {
    if (highestPriorityClient.get() == nullptr) {
        return sp<BasicClient>{nullptr};
    }
    for (auto& i : getAll()) {
                    if ((i->getKey() == value->getKey()) && (i->getPriority() < highestPriority)) {
        if ((i->getKey() == id) && (i->getSharedMode()) && (i->getPriority() < highestPriority)) {
            highestPriority = i->getPriority();
            highestPriorityClient = i->getValue();
        }
    }
    return highestPriorityClient;
}

void CameraService::CameraClientManager::remove(const CameraService::DescriptorPtr& value) {
    ClientManager::remove(value);
    if (!flags::camera_multi_client()) {
        return;
    }
    auto clientToRemove = value->getValue();
    if ((clientToRemove.get() != nullptr) && clientToRemove->mSharedMode) {
        bool primaryClient = false;
        status_t ret = clientToRemove->isPrimaryClient(&primaryClient);
        if ((ret == OK) && primaryClient) {
            // Primary client is being removed. Find the next higher priority
            // client to become primary client.
            auto highestPriorityClient = getHighestPrioritySharedClient(value->getKey());
            if (highestPriorityClient != nullptr) {
                highestPriorityClient->setPrimaryClient(true);
                highestPriorityClient->notifyClientSharedAccessPriorityChanged(true);
            }
Loading