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

Commit c4e4425c authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Merge "add native IPlayer interface implementation" into oc-dev am:...

Merge "Merge "add native IPlayer interface implementation" into oc-dev am: a9034e0e am: e5ed4fc2"
parents 4d43edb9 3bbd7673
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ cc_library_shared {
        "IEffect.cpp",
        "IEffectClient.cpp",
        "ToneGenerator.cpp",
        "PlayerBase.cpp",
        "TrackPlayerBase.cpp",
    ],
    shared_libs: [
        "liblog",
@@ -30,6 +32,7 @@ cc_library_shared {
        "libbinder",
        "libdl",
        "libaudioutils",
        "libaudiomanager",
    ],
    export_shared_lib_headers: ["libbinder"],

+165 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#include <binder/IServiceManager.h>
#include <media/PlayerBase.h>

#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))

namespace android {

//--------------------------------------------------------------------------------------------------
PlayerBase::PlayerBase() : BnPlayer(),
        mPanMultiplierL(1.0f), mPanMultiplierR(1.0f),
        mVolumeMultiplierL(1.0f), mVolumeMultiplierR(1.0f),
        mPIId(PLAYER_PIID_INVALID), mLastReportedEvent(PLAYER_STATE_UNKNOWN)
{
    ALOGD("PlayerBase::PlayerBase()");
    // use checkService() to avoid blocking if audio service is not up yet
    sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio"));
    if (binder == 0) {
        ALOGE("PlayerBase(): binding to audio service failed, service up?");
    } else {
        mAudioManager = interface_cast<IAudioManager>(binder);
    }
}


PlayerBase::~PlayerBase() {
    ALOGD("PlayerBase::~PlayerBase()");
    baseDestroy();
}

void PlayerBase::init(player_type_t playerType, audio_usage_t usage) {
    if (mAudioManager == 0) {
                ALOGE("AudioPlayer realize: no audio service, player will not be registered");
    } else {
        mPIId = mAudioManager->trackPlayer(playerType, usage, AUDIO_CONTENT_TYPE_UNKNOWN, this);
    }
}

void PlayerBase::baseDestroy() {
    serviceReleasePlayer();
    if (mAudioManager != 0) {
        mAudioManager.clear();
    }
}

//------------------------------------------------------------------------------
void PlayerBase::servicePlayerEvent(player_state_t event) {
    if (mAudioManager != 0) {
        // only report state change
        Mutex::Autolock _l(mPlayerStateLock);
        if (event != mLastReportedEvent
                && mPIId != PLAYER_PIID_INVALID) {
            mLastReportedEvent = event;
            mAudioManager->playerEvent(mPIId, event);
        }
    }
}

void PlayerBase::serviceReleasePlayer() {
    if (mAudioManager != 0
            && mPIId != PLAYER_PIID_INVALID) {
        mAudioManager->releasePlayer(mPIId);
    }
}

//FIXME temporary method while some AudioTrack state is outside of this class
void PlayerBase::reportEvent(player_state_t event) {
    servicePlayerEvent(event);
}

//------------------------------------------------------------------------------
// Implementation of IPlayer
void PlayerBase::start() {
    if (playerStart() == NO_ERROR) {
        ALOGD("PlayerBase::start() from IPlayer");
        servicePlayerEvent(PLAYER_STATE_STARTED);
    } else {
        ALOGD("PlayerBase::start() no AudioTrack to start from IPlayer");
    }
}

void PlayerBase::pause() {
    if (playerPause() == NO_ERROR) {
        ALOGD("PlayerBase::pause() from IPlayer");
        servicePlayerEvent(PLAYER_STATE_PAUSED);
    } else {
        ALOGD("PlayerBase::pause() no AudioTrack to pause from IPlayer");
    }
}


void PlayerBase::stop() {
    if (playerStop() == NO_ERROR) {
        ALOGD("PlayerBase::stop() from IPlayer");
        servicePlayerEvent(PLAYER_STATE_STOPPED);
    } else {
        ALOGD("PlayerBase::stop() no AudioTrack to stop from IPlayer");
    }
}

void PlayerBase::setVolume(float vol) {
    {
        Mutex::Autolock _l(mSettingsLock);
        mVolumeMultiplierL = vol;
        mVolumeMultiplierR = vol;
    }
    if (playerSetVolume() == NO_ERROR) {
        ALOGD("PlayerBase::setVolume() from IPlayer");
    } else {
        ALOGD("PlayerBase::setVolume() no AudioTrack for volume control from IPlayer");
    }
}

void PlayerBase::setPan(float pan) {
    {
        Mutex::Autolock _l(mSettingsLock);
        pan = min(max(-1.0f, pan), 1.0f);
        if (pan >= 0.0f) {
            mPanMultiplierL = 1.0f - pan;
            mPanMultiplierR = 1.0f;
        } else {
            mPanMultiplierL = 1.0f;
            mPanMultiplierR = 1.0f + pan;
        }
    }
    if (playerSetVolume() == NO_ERROR) {
        ALOGD("PlayerBase::setPan() from IPlayer");
    } else {
        ALOGD("PlayerBase::setPan() no AudioTrack for volume control from IPlayer");
    }
}

void PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
    ALOGW("setStartDelay() is not supported");
}

void PlayerBase::applyVolumeShaper(
        const sp<VolumeShaper::Configuration>& configuration  __unused,
        const sp<VolumeShaper::Operation>& operation __unused) {
    ALOGW("applyVolumeShaper() is not supported");
}

status_t PlayerBase::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    return BnPlayer::onTransact(code, data, reply, flags);
}

} // namespace android
+121 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#include <media/TrackPlayerBase.h>

namespace android {

//--------------------------------------------------------------------------------------------------
TrackPlayerBase::TrackPlayerBase() : PlayerBase(),
        mPlayerVolumeL(1.0f), mPlayerVolumeR(1.0f)
{
    ALOGD("TrackPlayerBase::TrackPlayerBase()");
}


TrackPlayerBase::~TrackPlayerBase() {
    ALOGD("TrackPlayerBase::~TrackPlayerBase()");
    doDestroy();
}

void TrackPlayerBase::init(AudioTrack* pat, player_type_t playerType, audio_usage_t usage) {
    PlayerBase::init(playerType, usage);
    mAudioTrack = pat;
}

void TrackPlayerBase::destroy() {
    doDestroy();
    baseDestroy();
}

void TrackPlayerBase::doDestroy() {
    if (mAudioTrack != 0) {
        mAudioTrack->stop();
        // Note that there may still be another reference in post-unlock phase of SetPlayState
        mAudioTrack.clear();
    }
}

void TrackPlayerBase::setPlayerVolume(float vl, float vr) {
    {
        Mutex::Autolock _l(mSettingsLock);
        mPlayerVolumeL = vl;
        mPlayerVolumeR = vr;
    }
    doSetVolume();
}

//------------------------------------------------------------------------------
// Implementation of IPlayer
status_t TrackPlayerBase::playerStart() {
    status_t status = NO_INIT;
    if (mAudioTrack != 0) {
        status = mAudioTrack->start();
    }
    return status;
}

status_t TrackPlayerBase::playerPause() {
    status_t status = NO_INIT;
    if (mAudioTrack != 0) {
        mAudioTrack->pause();
        status = NO_ERROR;
    }
    return status;
}


status_t TrackPlayerBase::playerStop() {
    status_t status = NO_INIT;
    if (mAudioTrack != 0) {
        mAudioTrack->stop();
        status = NO_ERROR;
    }
    return status;
}

status_t TrackPlayerBase::playerSetVolume() {
    return doSetVolume();
}

status_t TrackPlayerBase::doSetVolume() {
    status_t status = NO_INIT;
    if (mAudioTrack != 0) {
        float tl = mPlayerVolumeL * mPanMultiplierL * mVolumeMultiplierL;
        float tr = mPlayerVolumeR * mPanMultiplierR * mVolumeMultiplierR;
        mAudioTrack->setVolume(tl, tr);
        status = NO_ERROR;
    }
    return status;
}


void TrackPlayerBase::applyVolumeShaper(
        const sp<VolumeShaper::Configuration>& configuration,
        const sp<VolumeShaper::Operation>& operation) {
    if (mAudioTrack != 0) {
        ALOGD("TrackPlayerBase::applyVolumeShaper() from IPlayer");
        VolumeShaper::Status status = mAudioTrack->applyVolumeShaper(configuration, operation);
        if (status < 0) { // a non-negative value is the volume shaper id.
            ALOGE("TrackPlayerBase::applyVolumeShaper() failed with status %d", status);
        }
    } else {
        ALOGD("TrackPlayerBase::applyVolumeShaper()"
                " no AudioTrack for volume control from IPlayer");
    }
}

} // namespace android
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#ifndef __ANDROID_PLAYER_BASE_H__
#define __ANDROID_PLAYER_BASE_H__

#include <audiomanager/IPlayer.h>
#include <audiomanager/AudioManager.h>
#include <audiomanager/IAudioManager.h>


namespace android {

class PlayerBase : public BnPlayer
{
public:
    explicit PlayerBase();
    virtual ~PlayerBase();

    virtual void destroy() = 0;

    //IPlayer implementation
    virtual void start();
    virtual void pause();
    virtual void stop();
    virtual void setVolume(float vol);
    virtual void setPan(float pan);
    virtual void setStartDelayMs(int32_t delayMs);
    virtual void applyVolumeShaper(
            const sp<VolumeShaper::Configuration>& configuration,
            const sp<VolumeShaper::Operation>& operation) override;

    virtual status_t onTransact(
                uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);


            //FIXME temporary method while some player state is outside of this class
            void reportEvent(player_state_t event);

protected:

            void init(player_type_t playerType, audio_usage_t usage);
            void baseDestroy();

    //IPlayer methods handlers for derived classes
    virtual status_t playerStart()  { return NO_ERROR; }
    virtual status_t playerPause()  { return NO_ERROR; }
    virtual status_t playerStop()  { return NO_ERROR; }
    virtual status_t playerSetVolume()  { return NO_ERROR; }

    // mutex for IPlayer volume and pan, and player-specific volume
    Mutex mSettingsLock;

    // volume multipliers coming from the IPlayer volume and pan controls
    float mPanMultiplierL, mPanMultiplierR;
    float mVolumeMultiplierL, mVolumeMultiplierR;

private:
            // report events to AudioService
            void servicePlayerEvent(player_state_t event);
            void serviceReleasePlayer();

    // native interface to AudioService
    android::sp<android::IAudioManager> mAudioManager;

    // player interface ID, uniquely identifies the player in the system
    audio_unique_id_t mPIId;

    // Mutex for state reporting
    Mutex mPlayerStateLock;
    player_state_t mLastReportedEvent;
};

} // namespace android

#endif /* __ANDROID_PLAYER_BASE_H__ */
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#ifndef __ANDROID_TRACK_PLAYER_BASE_H__
#define __ANDROID_TRACK_PLAYER_BASE_H__

#include <media/AudioTrack.h>
#include <media/PlayerBase.h>

namespace android {

class TrackPlayerBase : public PlayerBase
{
public:
    explicit TrackPlayerBase();
    virtual ~TrackPlayerBase();

            void init(AudioTrack* pat, player_type_t playerType, audio_usage_t usage);
    virtual void destroy();

    //IPlayer implementation
    virtual void applyVolumeShaper(
            const sp<VolumeShaper::Configuration>& configuration,
            const sp<VolumeShaper::Operation>& operation);

    //FIXME move to protected field, so far made public to minimize changes to AudioTrack logic
    sp<AudioTrack> mAudioTrack;

            void setPlayerVolume(float vl, float vr);

protected:

    //PlayerBase virtuals
    virtual status_t playerStart();
    virtual status_t playerPause();
    virtual status_t playerStop();
    virtual status_t playerSetVolume();

private:
            void doDestroy();
            status_t doSetVolume();

    // volume coming from the player volume API
    float mPlayerVolumeL, mPlayerVolumeR;
};

} // namespace android

#endif /* __ANDROID_TRACK_PLAYER_BASE_H__ */