Home | History | Annotate | Download | only in libaudioclient
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <binder/IServiceManager.h>
     18 #include <media/PlayerBase.h>
     19 
     20 #define max(a, b) ((a) > (b) ? (a) : (b))
     21 #define min(a, b) ((a) < (b) ? (a) : (b))
     22 
     23 namespace android {
     24 
     25 using media::VolumeShaper;
     26 
     27 //--------------------------------------------------------------------------------------------------
     28 PlayerBase::PlayerBase() : BnPlayer(),
     29         mPanMultiplierL(1.0f), mPanMultiplierR(1.0f),
     30         mVolumeMultiplierL(1.0f), mVolumeMultiplierR(1.0f),
     31         mPIId(PLAYER_PIID_INVALID), mLastReportedEvent(PLAYER_STATE_UNKNOWN)
     32 {
     33     ALOGD("PlayerBase::PlayerBase()");
     34     // use checkService() to avoid blocking if audio service is not up yet
     35     sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio"));
     36     if (binder == 0) {
     37         ALOGE("PlayerBase(): binding to audio service failed, service up?");
     38     } else {
     39         mAudioManager = interface_cast<IAudioManager>(binder);
     40     }
     41 }
     42 
     43 
     44 PlayerBase::~PlayerBase() {
     45     ALOGD("PlayerBase::~PlayerBase()");
     46     baseDestroy();
     47 }
     48 
     49 void PlayerBase::init(player_type_t playerType, audio_usage_t usage) {
     50     if (mAudioManager == 0) {
     51                 ALOGE("AudioPlayer realize: no audio service, player will not be registered");
     52     } else {
     53         mPIId = mAudioManager->trackPlayer(playerType, usage, AUDIO_CONTENT_TYPE_UNKNOWN, this);
     54     }
     55 }
     56 
     57 void PlayerBase::baseDestroy() {
     58     serviceReleasePlayer();
     59     if (mAudioManager != 0) {
     60         mAudioManager.clear();
     61     }
     62 }
     63 
     64 //------------------------------------------------------------------------------
     65 void PlayerBase::servicePlayerEvent(player_state_t event) {
     66     if (mAudioManager != 0) {
     67         // only report state change
     68         Mutex::Autolock _l(mPlayerStateLock);
     69         if (event != mLastReportedEvent
     70                 && mPIId != PLAYER_PIID_INVALID) {
     71             mLastReportedEvent = event;
     72             mAudioManager->playerEvent(mPIId, event);
     73         }
     74     }
     75 }
     76 
     77 void PlayerBase::serviceReleasePlayer() {
     78     if (mAudioManager != 0
     79             && mPIId != PLAYER_PIID_INVALID) {
     80         mAudioManager->releasePlayer(mPIId);
     81     }
     82 }
     83 
     84 //FIXME temporary method while some player state is outside of this class
     85 void PlayerBase::reportEvent(player_state_t event) {
     86     servicePlayerEvent(event);
     87 }
     88 
     89 status_t PlayerBase::startWithStatus() {
     90     status_t status = playerStart();
     91     if (status == NO_ERROR) {
     92         servicePlayerEvent(PLAYER_STATE_STARTED);
     93     } else {
     94         ALOGW("PlayerBase::start() error %d", status);
     95     }
     96     return status;
     97 }
     98 
     99 status_t PlayerBase::pauseWithStatus() {
    100     status_t status = playerPause();
    101     if (status == NO_ERROR) {
    102         servicePlayerEvent(PLAYER_STATE_PAUSED);
    103     } else {
    104         ALOGW("PlayerBase::pause() error %d", status);
    105     }
    106     return status;
    107 }
    108 
    109 
    110 status_t PlayerBase::stopWithStatus() {
    111     status_t status = playerStop();
    112     if (status == NO_ERROR) {
    113         servicePlayerEvent(PLAYER_STATE_STOPPED);
    114     } else {
    115         ALOGW("PlayerBase::stop() error %d", status);
    116     }
    117     return status;
    118 }
    119 
    120 //------------------------------------------------------------------------------
    121 // Implementation of IPlayer
    122 binder::Status PlayerBase::start() {
    123     ALOGD("PlayerBase::start() from IPlayer");
    124     (void)startWithStatus();
    125     return binder::Status::ok();
    126 }
    127 
    128 binder::Status PlayerBase::pause() {
    129     ALOGD("PlayerBase::pause() from IPlayer");
    130     (void)pauseWithStatus();
    131     return binder::Status::ok();
    132 }
    133 
    134 
    135 binder::Status PlayerBase::stop() {
    136     ALOGD("PlayerBase::stop() from IPlayer");
    137     (void)stopWithStatus();
    138     return binder::Status::ok();
    139 }
    140 
    141 binder::Status PlayerBase::setVolume(float vol) {
    142     ALOGD("PlayerBase::setVolume() from IPlayer");
    143     {
    144         Mutex::Autolock _l(mSettingsLock);
    145         mVolumeMultiplierL = vol;
    146         mVolumeMultiplierR = vol;
    147     }
    148     status_t status = playerSetVolume();
    149     if (status != NO_ERROR) {
    150         ALOGW("PlayerBase::setVolume() error %d", status);
    151     }
    152     return binder::Status::fromStatusT(status);
    153 }
    154 
    155 binder::Status PlayerBase::setPan(float pan) {
    156     ALOGD("PlayerBase::setPan() from IPlayer");
    157     {
    158         Mutex::Autolock _l(mSettingsLock);
    159         pan = min(max(-1.0f, pan), 1.0f);
    160         if (pan >= 0.0f) {
    161             mPanMultiplierL = 1.0f - pan;
    162             mPanMultiplierR = 1.0f;
    163         } else {
    164             mPanMultiplierL = 1.0f;
    165             mPanMultiplierR = 1.0f + pan;
    166         }
    167     }
    168     status_t status = playerSetVolume();
    169     if (status != NO_ERROR) {
    170         ALOGW("PlayerBase::setPan() error %d", status);
    171     }
    172     return binder::Status::fromStatusT(status);
    173 }
    174 
    175 binder::Status PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
    176     ALOGW("setStartDelay() is not supported");
    177     return binder::Status::ok();
    178 }
    179 
    180 binder::Status PlayerBase::applyVolumeShaper(
    181             const VolumeShaper::Configuration& configuration __unused,
    182             const VolumeShaper::Operation& operation __unused) {
    183     ALOGW("applyVolumeShaper() is not supported");
    184     return binder::Status::ok();
    185 }
    186 
    187 } // namespace android
    188