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 //--------------------------------------------------------------------------------------------------
PlayerBase()26 PlayerBase::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
~PlayerBase()42 PlayerBase::~PlayerBase() {
43 ALOGD("PlayerBase::~PlayerBase()");
44 baseDestroy();
45 }
46
init(player_type_t playerType,audio_usage_t usage)47 void 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
baseDestroy()55 void PlayerBase::baseDestroy() {
56 serviceReleasePlayer();
57 if (mAudioManager != 0) {
58 mAudioManager.clear();
59 }
60 }
61
62 //------------------------------------------------------------------------------
servicePlayerEvent(player_state_t event)63 void 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
serviceReleasePlayer()75 void 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
reportEvent(player_state_t event)83 void PlayerBase::reportEvent(player_state_t event) {
84 servicePlayerEvent(event);
85 }
86
startWithStatus()87 status_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
start()100 void PlayerBase::start() {
101 (void)startWithStatus();
102 }
103
pause()104 void 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
stop()114 void 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
setVolume(float vol)123 void 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
setPan(float pan)136 void 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
setStartDelayMs(int32_t delayMs __unused)155 void PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
156 ALOGW("setStartDelay() is not supported");
157 }
158
applyVolumeShaper(const sp<VolumeShaper::Configuration> & configuration __unused,const sp<VolumeShaper::Operation> & operation __unused)159 void PlayerBase::applyVolumeShaper(
160 const sp<VolumeShaper::Configuration>& configuration __unused,
161 const sp<VolumeShaper::Operation>& operation __unused) {
162 ALOGW("applyVolumeShaper() is not supported");
163 }
164
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)165 status_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