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

Commit 6dc08b36 authored by Eric Laurent's avatar Eric Laurent
Browse files

Fix issue 3225810.

Take a wake lock whenever A2DP output stream is active.

Change-Id: Ie50e6d4cb34c8a1ba97b301ef25e10aeb153d8f3
parent 6bdbcd74
Loading
Loading
Loading
Loading
+55 −34
Original line number Diff line number Diff line
@@ -23,10 +23,13 @@

#include "A2dpAudioInterface.h"
#include "audio/liba2dp.h"

#include <hardware_legacy/power.h>

namespace android {

static const char *sA2dpWakeLock = "A2dpOutputStream";
#define MAX_WRITE_RETRIES  5

// ----------------------------------------------------------------------------

//AudioHardwareInterface* A2dpAudioInterface::createA2dpInterface()
@@ -263,17 +266,17 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
{
    LOGV("A2dpAudioStreamOut destructor");
    standby();
    close();
    LOGV("A2dpAudioStreamOut destructor returning from close()");
}

ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
{
    status_t status = -1;
    {
        Mutex::Autolock lock(mLock);

        size_t remaining = bytes;
    status_t status = -1;

        if (!mBluetoothEnabled || mClosing || mSuspended) {
            LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
@@ -282,25 +285,36 @@ ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t
            goto Error;
        }

        if (mStandby) {
            acquire_wake_lock (PARTIAL_WAKE_LOCK, sA2dpWakeLock);
            mStandby = false;
        }

        status = init();
        if (status < 0)
            goto Error;

    while (remaining > 0) {
        int retries = MAX_WRITE_RETRIES;
        while (remaining > 0 && retries) {
            status = a2dp_write(mData, buffer, remaining);
        if (status <= 0) {
            if (status < 0) {
                LOGE("a2dp_write failed err: %d\n", status);
                goto Error;
            }
            if (status == 0) {
                retries--;
            }
            remaining -= status;
        buffer = ((char *)buffer) + status;
            buffer = (char *)buffer + status;
        }

    mStandby = false;

        return bytes;

    }
Error:

    standby();

    // Simulate audio output timing in case of error
    usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);

@@ -324,18 +338,21 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::init()

status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
{
    int result = 0;

    if (mClosing) {
        LOGV("Ignore standby, closing");
        return result;
    Mutex::Autolock lock(mLock);
    return standby_l();
}

    Mutex::Autolock lock(mLock);
status_t A2dpAudioInterface::A2dpAudioStreamOut::standby_l()
{
    int result = NO_ERROR;

    if (!mStandby) {
        LOGV_IF(mClosing || !mBluetoothEnabled, "Standby skip stop: closing %d enabled %d",
                mClosing, mBluetoothEnabled);
        if (!mClosing && mBluetoothEnabled) {
            result = a2dp_stop(mData);
        if (result == 0)
        }
        release_wake_lock(sA2dpWakeLock);
        mStandby = true;
    }

@@ -362,6 +379,9 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& ke
    key = String8("closing");
    if (param.get(key, value) == NO_ERROR) {
        mClosing = (value == "true");
        if (mClosing) {
            standby();
        }
        param.remove(key);
    }
    key = AudioParameter::keyRouting;
@@ -444,6 +464,7 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::close()

status_t A2dpAudioInterface::A2dpAudioStreamOut::close_l()
{
    standby_l();
    if (mData) {
        LOGV("A2dpAudioStreamOut::close_l() calling a2dp_cleanup(mData)");
        a2dp_cleanup(mData);
+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ private:
                status_t    setAddress(const char* address);
                status_t    setBluetoothEnabled(bool enabled);
                status_t    setSuspended(bool onOff);
                status_t    standby_l();

    private:
                int         mFd;