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 //--------------------------------------------------------------------------------------------------
PlayerBase()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
~PlayerBase()44 PlayerBase::~PlayerBase() {
45 ALOGD("PlayerBase::~PlayerBase()");
46 baseDestroy();
47 }
48
init(player_type_t playerType,audio_usage_t usage)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
baseDestroy()57 void PlayerBase::baseDestroy() {
58 serviceReleasePlayer();
59 if (mAudioManager != 0) {
60 mAudioManager.clear();
61 }
62 }
63
64 //------------------------------------------------------------------------------
servicePlayerEvent(player_state_t event)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
serviceReleasePlayer()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
reportEvent(player_state_t event)85 void PlayerBase::reportEvent(player_state_t event) {
86 servicePlayerEvent(event);
87 }
88
startWithStatus()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
pauseWithStatus()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
stopWithStatus()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
start()122 binder::Status PlayerBase::start() {
123 ALOGD("PlayerBase::start() from IPlayer");
124 (void)startWithStatus();
125 return binder::Status::ok();
126 }
127
pause()128 binder::Status PlayerBase::pause() {
129 ALOGD("PlayerBase::pause() from IPlayer");
130 (void)pauseWithStatus();
131 return binder::Status::ok();
132 }
133
134
stop()135 binder::Status PlayerBase::stop() {
136 ALOGD("PlayerBase::stop() from IPlayer");
137 (void)stopWithStatus();
138 return binder::Status::ok();
139 }
140
setVolume(float vol)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
setPan(float pan)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
setStartDelayMs(int32_t delayMs __unused)175 binder::Status PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
176 ALOGW("setStartDelay() is not supported");
177 return binder::Status::ok();
178 }
179
applyVolumeShaper(const VolumeShaper::Configuration & configuration __unused,const VolumeShaper::Operation & operation __unused)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