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 23namespace android { 24 25//-------------------------------------------------------------------------------------------------- 26PlayerBase::PlayerBase() : BnPlayer(), 27 mPanMultiplierL(1.0f), mPanMultiplierR(1.0f), 28 mVolumeMultiplierL(1.0f), mVolumeMultiplierR(1.0f), 29 mPIId(PLAYER_PIID_INVALID), mLastReportedEvent(PLAYER_STATE_UNKNOWN) 30{ 31 ALOGD("PlayerBase::PlayerBase()"); 32 // use checkService() to avoid blocking if audio service is not up yet 33 sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio")); 34 if (binder == 0) { 35 ALOGE("PlayerBase(): binding to audio service failed, service up?"); 36 } else { 37 mAudioManager = interface_cast<IAudioManager>(binder); 38 } 39} 40 41 42PlayerBase::~PlayerBase() { 43 ALOGD("PlayerBase::~PlayerBase()"); 44 baseDestroy(); 45} 46 47void PlayerBase::init(player_type_t playerType, audio_usage_t usage) { 48 if (mAudioManager == 0) { 49 ALOGE("AudioPlayer realize: no audio service, player will not be registered"); 50 } else { 51 mPIId = mAudioManager->trackPlayer(playerType, usage, AUDIO_CONTENT_TYPE_UNKNOWN, this); 52 } 53} 54 55void PlayerBase::baseDestroy() { 56 serviceReleasePlayer(); 57 if (mAudioManager != 0) { 58 mAudioManager.clear(); 59 } 60} 61 62//------------------------------------------------------------------------------ 63void PlayerBase::servicePlayerEvent(player_state_t event) { 64 if (mAudioManager != 0) { 65 // only report state change 66 Mutex::Autolock _l(mPlayerStateLock); 67 if (event != mLastReportedEvent 68 && mPIId != PLAYER_PIID_INVALID) { 69 mLastReportedEvent = event; 70 mAudioManager->playerEvent(mPIId, event); 71 } 72 } 73} 74 75void PlayerBase::serviceReleasePlayer() { 76 if (mAudioManager != 0 77 && mPIId != PLAYER_PIID_INVALID) { 78 mAudioManager->releasePlayer(mPIId); 79 } 80} 81 82//FIXME temporary method while some AudioTrack state is outside of this class 83void PlayerBase::reportEvent(player_state_t event) { 84 servicePlayerEvent(event); 85} 86 87status_t PlayerBase::startWithStatus() { 88 status_t status = playerStart(); 89 if (status == NO_ERROR) { 90 ALOGD("PlayerBase::start() from IPlayer"); 91 servicePlayerEvent(PLAYER_STATE_STARTED); 92 } else { 93 ALOGD("PlayerBase::start() no AudioTrack to start from IPlayer"); 94 } 95 return status; 96} 97 98//------------------------------------------------------------------------------ 99// Implementation of IPlayer 100void PlayerBase::start() { 101 (void)startWithStatus(); 102} 103 104void PlayerBase::pause() { 105 if (playerPause() == NO_ERROR) { 106 ALOGD("PlayerBase::pause() from IPlayer"); 107 servicePlayerEvent(PLAYER_STATE_PAUSED); 108 } else { 109 ALOGD("PlayerBase::pause() no AudioTrack to pause from IPlayer"); 110 } 111} 112 113 114void PlayerBase::stop() { 115 if (playerStop() == NO_ERROR) { 116 ALOGD("PlayerBase::stop() from IPlayer"); 117 servicePlayerEvent(PLAYER_STATE_STOPPED); 118 } else { 119 ALOGD("PlayerBase::stop() no AudioTrack to stop from IPlayer"); 120 } 121} 122 123void PlayerBase::setVolume(float vol) { 124 { 125 Mutex::Autolock _l(mSettingsLock); 126 mVolumeMultiplierL = vol; 127 mVolumeMultiplierR = vol; 128 } 129 if (playerSetVolume() == NO_ERROR) { 130 ALOGD("PlayerBase::setVolume() from IPlayer"); 131 } else { 132 ALOGD("PlayerBase::setVolume() no AudioTrack for volume control from IPlayer"); 133 } 134} 135 136void PlayerBase::setPan(float pan) { 137 { 138 Mutex::Autolock _l(mSettingsLock); 139 pan = min(max(-1.0f, pan), 1.0f); 140 if (pan >= 0.0f) { 141 mPanMultiplierL = 1.0f - pan; 142 mPanMultiplierR = 1.0f; 143 } else { 144 mPanMultiplierL = 1.0f; 145 mPanMultiplierR = 1.0f + pan; 146 } 147 } 148 if (playerSetVolume() == NO_ERROR) { 149 ALOGD("PlayerBase::setPan() from IPlayer"); 150 } else { 151 ALOGD("PlayerBase::setPan() no AudioTrack for volume control from IPlayer"); 152 } 153} 154 155void PlayerBase::setStartDelayMs(int32_t delayMs __unused) { 156 ALOGW("setStartDelay() is not supported"); 157} 158 159void PlayerBase::applyVolumeShaper( 160 const sp<VolumeShaper::Configuration>& configuration __unused, 161 const sp<VolumeShaper::Operation>& operation __unused) { 162 ALOGW("applyVolumeShaper() is not supported"); 163} 164 165status_t PlayerBase::onTransact( 166 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 167{ 168 return BnPlayer::onTransact(code, data, reply, flags); 169} 170 171} // namespace android 172