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

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

Merge "audio policy: refactor record activity tracking (AudioSession)"

parents 0f7d299c a18dced5
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -34,12 +34,4 @@ public:
    virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
};

class AudioIODescriptorUpdateListener
{
public:
    virtual ~AudioIODescriptorUpdateListener() {};

    virtual void onIODescriptorUpdate() const = 0;
};

} // namespace android
+8 −2
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ public:
    AudioSessionCollection getAudioSessions(bool activeOnly) const;
    size_t getAudioSessionCount(bool activeOnly) const;
    audio_source_t getHighestPrioritySource(bool activeOnly) const;
    void changeRefCount(audio_session_t session, int delta);


    // implementation of AudioIODescriptorInterface
    audio_config_base_t getConfig() const override;
@@ -79,14 +81,17 @@ public:
                  audio_input_flags_t flags,
                  audio_io_handle_t *input);
    // Called when a stream is about to be started.
    // Note: called after AudioSession::changeActiveCount(1)
    // Note: called after changeRefCount(session, 1)
    status_t start();
    // Called after a stream is stopped
    // Note: called after AudioSession::changeActiveCount(-1)
    // Note: called after changeRefCount(session, -1)
    void stop();
    void close();

private:

    void updateSessionRecordingConfiguration(int event, const sp<AudioSession>& audioSession);

    audio_patch_handle_t          mPatchHandle;
    audio_port_handle_t           mId;
    // audio sessions attached to this input
@@ -99,6 +104,7 @@ private:
    // We also inherit sessions from the preempted input to avoid a 3 way preemption loop etc...
    SortedVector<audio_session_t> mPreemptedSessions;
    AudioPolicyClientInterface *mClientInterface;
    uint32_t mGlobalRefCount;  // non-session-specific ref count
};

class AudioInputCollection :
+6 −18
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ namespace android {

class AudioPolicyClientInterface;

class AudioSession : public RefBase, public AudioIODescriptorUpdateListener
class AudioSession : public RefBase
{
public:
    AudioSession(audio_session_t session,
@@ -39,9 +39,7 @@ public:
                 audio_channel_mask_t channelMask,
                 audio_input_flags_t flags,
                 uid_t uid,
                 bool isSoundTrigger,
                 AudioMix* policyMix,
                 AudioPolicyClientInterface *clientInterface);
                 bool isSoundTrigger);

    status_t dump(int fd, int spaces, int index) const;

@@ -50,6 +48,8 @@ public:
    audio_format_t format() const { return mConfig.format; }
    uint32_t sampleRate() const { return mConfig.sample_rate; }
    audio_channel_mask_t channelMask() const { return mConfig.channel_mask; }
    audio_config_base config() const { return mConfig; }
    record_client_info_t recordClientInfo() const { return mRecordClientInfo; }
    audio_input_flags_t flags() const { return mFlags; }
    uid_t uid() const { return mRecordClientInfo.uid; }
    void setUid(uid_t uid) { mRecordClientInfo.uid = uid; }
@@ -63,10 +63,6 @@ public:
    uint32_t changeOpenCount(int delta);
    uint32_t changeActiveCount(int delta);

    void setInfoProvider(AudioIODescriptorInterface *provider);
    // implementation of AudioIODescriptorUpdateListener
    virtual void onIODescriptorUpdate() const;

private:
    record_client_info_t mRecordClientInfo;
    const struct audio_config_base mConfig;
@@ -75,19 +71,14 @@ private:
    bool mSilenced;
    uint32_t  mOpenCount;
    uint32_t  mActiveCount;
    AudioMix* mPolicyMix; // non NULL when used by a dynamic policy
    AudioPolicyClientInterface* mClientInterface;
    const AudioIODescriptorInterface* mInfoProvider;
};

class AudioSessionCollection :
    public DefaultKeyedVector<audio_session_t, sp<AudioSession> >,
    public AudioIODescriptorUpdateListener
    public DefaultKeyedVector<audio_session_t, sp<AudioSession> >
{
public:
    status_t addSession(audio_session_t session,
                             const sp<AudioSession>& audioSession,
                             AudioIODescriptorInterface *provider);
                             const sp<AudioSession>& audioSession);

    status_t removeSession(audio_session_t session);

@@ -99,9 +90,6 @@ public:
    bool isSourceActive(audio_source_t source) const;
    audio_source_t getHighestPrioritySource(bool activeOnly) const;

    // implementation of AudioIODescriptorUpdateListener
    virtual void onIODescriptorUpdate() const;

    status_t dump(int fd, int spaces) const;
};

+68 −4
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile,
    : mIoHandle(0),
      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
      mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0),
      mClientInterface(clientInterface)
      mClientInterface(clientInterface), mGlobalRefCount(0)
{
    if (profile != NULL) {
        profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
@@ -164,7 +164,7 @@ size_t AudioInputDescriptor::getAudioSessionCount(bool activeOnly) const

status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
                         const sp<AudioSession>& audioSession) {
    return mSessions.addSession(session, audioSession, /*AudioIODescriptorInterface*/this);
    return mSessions.addSession(session, audioSession);
}

status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
@@ -179,7 +179,11 @@ audio_patch_handle_t AudioInputDescriptor::getPatchHandle() const
void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
{
    mPatchHandle = handle;
    mSessions.onIODescriptorUpdate();
    for (size_t i = 0; i < mSessions.size(); i++) {
        if (mSessions[i]->activeCount() > 0) {
            updateSessionRecordingConfiguration(RECORD_CONFIG_EVENT_START, mSessions[i]);
        }
    }
}

audio_config_base_t AudioInputDescriptor::getConfig() const
@@ -266,7 +270,7 @@ void AudioInputDescriptor::close()
        LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
                            __FUNCTION__, mProfile->curOpenCount);
        // do not call stop() here as stop() is supposed to be called after
        // AudioSession::changeActiveCount(-1) and we don't know how many sessions
        //  changeRefCount(session, -1) and we don't know how many sessions
        // are still active at this time
        if (isActive()) {
            mProfile->curActiveCount--;
@@ -276,6 +280,66 @@ void AudioInputDescriptor::close()
    }
}

void AudioInputDescriptor::changeRefCount(audio_session_t session, int delta)
{
    sp<AudioSession> audioSession = mSessions.valueFor(session);
    if (audioSession == 0) {
        return;
    }
    // handle session-independent ref count
    uint32_t oldGlobalRefCount = mGlobalRefCount;
    if ((delta + (int)mGlobalRefCount) < 0) {
        ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
        delta = -((int)mGlobalRefCount);
    }
    mGlobalRefCount += delta;
    if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
        {
            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
                                                            MIX_STATE_MIXING);
        }

    } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
        {
            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
                                                            MIX_STATE_IDLE);
        }
    }

    uint32_t oldActiveCount = audioSession->activeCount();
    if ((delta + (int)oldActiveCount) < 0) {
        ALOGW("changeRefCount() invalid delta %d for sesion %d active count %d",
              delta, session, oldActiveCount);
        delta = -((int)oldActiveCount);
    }

    audioSession->changeActiveCount(delta);

    int event = RECORD_CONFIG_EVENT_NONE;
    if ((oldActiveCount == 0) && (audioSession->activeCount() > 0)) {
        event = RECORD_CONFIG_EVENT_START;
    } else if ((oldActiveCount > 0) && (audioSession->activeCount() == 0)) {
        event = RECORD_CONFIG_EVENT_STOP;
    }
    if (event != RECORD_CONFIG_EVENT_NONE) {
        updateSessionRecordingConfiguration(event, audioSession);
    }

}

void AudioInputDescriptor::updateSessionRecordingConfiguration(
    int event, const sp<AudioSession>& audioSession) {

    const audio_config_base_t sessionConfig = audioSession->config();
    const record_client_info_t recordClientInfo = audioSession->recordClientInfo();
    const audio_config_base_t config = getConfig();
    mClientInterface->onRecordingConfigurationUpdate(event,
                                                     &recordClientInfo, &sessionConfig,
                                                     &config, mPatchHandle);
}

status_t AudioInputDescriptor::dump(int fd)
{
    const size_t SIZE = 256;
+3 −66
Original line number Diff line number Diff line
@@ -35,14 +35,11 @@ AudioSession::AudioSession(audio_session_t session,
                           audio_channel_mask_t channelMask,
                           audio_input_flags_t flags,
                           uid_t uid,
                           bool isSoundTrigger,
                           AudioMix* policyMix,
                           AudioPolicyClientInterface *clientInterface) :
                           bool isSoundTrigger) :
    mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
    mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
    mFlags(flags), mIsSoundTrigger(isSoundTrigger),
    mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface),
    mInfoProvider(NULL)
    mOpenCount(1), mActiveCount(0)
{
}

@@ -60,7 +57,6 @@ uint32_t AudioSession::changeOpenCount(int delta)

uint32_t AudioSession::changeActiveCount(int delta)
{
    const uint32_t oldActiveCount = mActiveCount;
    if ((delta + (int)mActiveCount) < 0) {
        ALOGW("%s invalid delta %d, active count %d",
              __FUNCTION__, delta, mActiveCount);
@@ -68,34 +64,6 @@ uint32_t AudioSession::changeActiveCount(int delta)
    }
    mActiveCount += delta;
    ALOGV("%s active count %d", __FUNCTION__, mActiveCount);
    int event = RECORD_CONFIG_EVENT_NONE;

    if ((oldActiveCount == 0) && (mActiveCount > 0)) {
        event = RECORD_CONFIG_EVENT_START;
    } else if ((oldActiveCount > 0) && (mActiveCount == 0)) {
        event = RECORD_CONFIG_EVENT_STOP;
    }

    if (event != RECORD_CONFIG_EVENT_NONE) {
        // Dynamic policy callback:
        // if input maps to a dynamic policy with an activity listener, notify of state change
        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
        {
            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
                    (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
        }

        // Recording configuration callback:
        const AudioIODescriptorInterface* provider = mInfoProvider;
        const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
                AUDIO_CONFIG_BASE_INITIALIZER;
        const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
                AUDIO_PATCH_HANDLE_NONE;
        if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
            mClientInterface->onRecordingConfigurationUpdate(event, &mRecordClientInfo,
                    &mConfig, &deviceConfig, patchHandle);
        }
    }

    return mActiveCount;
}
@@ -114,27 +82,6 @@ bool AudioSession::matches(const sp<AudioSession> &other) const
    return false;
}

void AudioSession::setInfoProvider(AudioIODescriptorInterface *provider)
{
    mInfoProvider = provider;
}

void AudioSession::onIODescriptorUpdate() const
{
    if (mActiveCount > 0) {
        // resend the callback after requerying the informations from the info provider
        const AudioIODescriptorInterface* provider = mInfoProvider;
        const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
                AUDIO_CONFIG_BASE_INITIALIZER;
        const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
                AUDIO_PATCH_HANDLE_NONE;
        if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
            mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
                    &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
        }
    }
}

status_t AudioSession::dump(int fd, int spaces, int index) const
{
    const size_t SIZE = 256;
@@ -169,8 +116,7 @@ status_t AudioSession::dump(int fd, int spaces, int index) const
}

status_t AudioSessionCollection::addSession(audio_session_t session,
                                         const sp<AudioSession>& audioSession,
                                         AudioIODescriptorInterface *provider)
                                         const sp<AudioSession>& audioSession)
{
    ssize_t index = indexOfKey(session);

@@ -178,7 +124,6 @@ status_t AudioSessionCollection::addSession(audio_session_t session,
        ALOGW("addSession() session %d already in", session);
        return ALREADY_EXISTS;
    }
    audioSession->setInfoProvider(provider);
    add(session, audioSession);
    ALOGV("addSession() session %d  client %d source %d",
            session, audioSession->uid(), audioSession->inputSource());
@@ -194,7 +139,6 @@ status_t AudioSessionCollection::removeSession(audio_session_t session)
        return ALREADY_EXISTS;
    }
    ALOGV("removeSession() session %d", session);
    valueAt(index)->setInfoProvider(NULL);
    removeItemsAt(index);
    return NO_ERROR;
}
@@ -271,13 +215,6 @@ audio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly)
    return source;
}

void AudioSessionCollection::onIODescriptorUpdate() const
{
    for (size_t i = 0; i < size(); i++) {
        valueAt(i)->onIODescriptorUpdate();
    }
}

status_t AudioSessionCollection::dump(int fd, int spaces) const
{
    const size_t SIZE = 256;
Loading