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

Commit 415af498 authored by jiabin's avatar jiabin
Browse files

Introduce notion of active devices.

The list of active devices is populated by the Engine.
The active devices are selected with the following rules:
1) If all of the preferred devices for media are available then they
   will all be used for the output.
2) If not, then the last connected removable device will be used.
3) If there are no removable devices then the default audio policy rule
   will be used.
In this CL, we only add a function to query active devices. In a future
CL we will use this list when opening an output.

Test: dumpsys
Bug: 160352965
Change-Id: I12f9ed24e1404264ad7055f3a7c73b444b33ee1a
parent b1c141b9
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -151,7 +151,23 @@ public:
    status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
            device_role_t role, AudioDeviceTypeAddrVector &devices) const override;

    DeviceVector getActiveMediaDevices(const DeviceVector& availableDevices) const override;

private:
    /**
     * Get media devices as the given role
     *
     * @param role the audio devices role
     * @param availableDevices all available devices
     * @param devices the DeviceVector to store devices as the given role
     * @return NO_ERROR if all devices associated to the given role are present in available devices
     *         NAME_NO_FOUND if there is no strategy for media or there are no devices associate to
     *         the given role
     *         NOT_ENOUGH_DATA if not all devices as given role are present in available devices
     */
    status_t getMediaDevicesForRole(device_role_t role, const DeviceVector& availableDevices,
            DeviceVector& devices) const;

    AudioPolicyManagerObserver *mApmObserver = nullptr;

    ProductStrategyMap mProductStrategies;
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ public:
    void setRemovableMediaDevices(sp<DeviceDescriptor> desc, audio_policy_dev_state_t state);
    std::vector<audio_devices_t> getLastRemovableMediaDevices(
            device_out_group_t group = GROUP_NONE) const;
    sp<DeviceDescriptor> getLastRemovableMediaDevice(
            const DeviceVector& excludedDevices, device_out_group_t group = GROUP_NONE) const;

private:
    struct DeviceGroupDescriptor {
+39 −0
Original line number Diff line number Diff line
@@ -588,6 +588,45 @@ status_t EngineBase::getDevicesForRoleAndCapturePreset(audio_source_t audioSourc
    return NO_ERROR;
}

status_t EngineBase::getMediaDevicesForRole(device_role_t role,
        const DeviceVector& availableDevices, DeviceVector& devices) const
{
    product_strategy_t strategy = getProductStrategyByName("STRATEGY_MEDIA" /*name*/);
    if (strategy == PRODUCT_STRATEGY_NONE) {
        strategy = getProductStrategyForStream(AUDIO_STREAM_MUSIC);
    }
    if (strategy == PRODUCT_STRATEGY_NONE) {
        return NAME_NOT_FOUND;
    }
    AudioDeviceTypeAddrVector deviceAddrVec;
    status_t status = getDevicesForRoleAndStrategy(strategy, role, deviceAddrVec);
    if (status != NO_ERROR) {
        return status;
    }
    devices = availableDevices.getDevicesFromDeviceTypeAddrVec(deviceAddrVec);
    return deviceAddrVec.size() == devices.size() ? NO_ERROR : NOT_ENOUGH_DATA;
}

DeviceVector EngineBase::getActiveMediaDevices(const DeviceVector& availableDevices) const
{
    // The priority of active devices as follows:
    // 1: the available preferred devices for media
    // 2: the latest connected removable media device that is enabled
    DeviceVector activeDevices;
    if (getMediaDevicesForRole(
            DEVICE_ROLE_PREFERRED, availableDevices, activeDevices) != NO_ERROR) {
        activeDevices.clear();
        DeviceVector disabledDevices;
        getMediaDevicesForRole(DEVICE_ROLE_DISABLED, availableDevices, disabledDevices);
        sp<DeviceDescriptor> device =
                mLastRemovableMediaDevices.getLastRemovableMediaDevice(disabledDevices);
        if (device != nullptr) {
            activeDevices.add(device);
        }
    }
    return activeDevices;
}

void EngineBase::dump(String8 *dst) const
{
    mProductStrategies.dump(dst, 2);
+11 −0
Original line number Diff line number Diff line
@@ -55,6 +55,17 @@ std::vector<audio_devices_t> LastRemovableMediaDevices::getLastRemovableMediaDev
    return ret;
}

sp<DeviceDescriptor> LastRemovableMediaDevices::getLastRemovableMediaDevice(
        const DeviceVector& excludedDevices, device_out_group_t group) const {
    for (auto iter = mMediaDevices.begin(); iter != mMediaDevices.end(); ++iter) {
        if ((group == GROUP_NONE || group == getDeviceOutGroup((iter->desc)->type())) &&
                !excludedDevices.contains(iter->desc)) {
            return iter->desc;
        }
    }
    return nullptr;
}

device_out_group_t LastRemovableMediaDevices::getDeviceOutGroup(audio_devices_t device) const
{
    switch (device) {
+6 −0
Original line number Diff line number Diff line
@@ -403,6 +403,12 @@ public:
    virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
            device_role_t role, AudioDeviceTypeAddrVector &devices) const = 0;

    /**
     * @brief getActiveMediaDevices returns which devices will most likely to be used for media
     * @param availableDevices all available devices
     * @return collection of active devices
     */
    virtual DeviceVector getActiveMediaDevices(const DeviceVector& availableDevices) const = 0;

    virtual void dump(String8 *dst) const = 0;