• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/AidlConversionUtil.h>
19 #include <media/PlayerBase.h>
20 
21 #define max(a, b) ((a) > (b) ? (a) : (b))
22 #define min(a, b) ((a) < (b) ? (a) : (b))
23 
24 namespace android {
25 using aidl_utils::binderStatusFromStatusT;
26 using media::VolumeShaperConfiguration;
27 using media::VolumeShaperOperation;
28 
29 //--------------------------------------------------------------------------------------------------
PlayerBase()30 PlayerBase::PlayerBase() : BnPlayer(),
31         mPanMultiplierL(1.0f), mPanMultiplierR(1.0f),
32         mVolumeMultiplierL(1.0f), mVolumeMultiplierR(1.0f),
33         mPIId(PLAYER_PIID_INVALID), mLastReportedEvent(PLAYER_STATE_UNKNOWN),
34         mLastReportedDeviceId(AUDIO_PORT_HANDLE_NONE)
35 {
36     ALOGD("PlayerBase::PlayerBase()");
37     // use checkService() to avoid blocking if audio service is not up yet
38     sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio"));
39     if (binder == 0) {
40         ALOGE("PlayerBase(): binding to audio service failed, service up?");
41     } else {
42         mAudioManager = interface_cast<IAudioManager>(binder);
43     }
44 }
45 
46 
~PlayerBase()47 PlayerBase::~PlayerBase() {
48     ALOGD("PlayerBase::~PlayerBase()");
49     baseDestroy();
50 }
51 
init(player_type_t playerType,audio_usage_t usage,audio_session_t sessionId)52 void PlayerBase::init(player_type_t playerType, audio_usage_t usage, audio_session_t sessionId) {
53     if (mAudioManager == 0) {
54                 ALOGE("AudioPlayer realize: no audio service, player will not be registered");
55     } else {
56         mPIId = mAudioManager->trackPlayer(playerType, usage, AUDIO_CONTENT_TYPE_UNKNOWN, this,
57                 sessionId);
58     }
59 }
60 
triggerPortIdUpdate(audio_port_handle_t portId) const61 void PlayerBase::triggerPortIdUpdate(audio_port_handle_t portId) const {
62     if (mAudioManager == nullptr) {
63         ALOGE("%s: no audio service, player %d will not update portId %d",
64               __func__,
65               mPIId,
66               portId);
67         return;
68     }
69 
70     if (mPIId != PLAYER_PIID_INVALID && portId != AUDIO_PORT_HANDLE_NONE) {
71         mAudioManager->playerEvent(mPIId, android::PLAYER_UPDATE_PORT_ID, portId);
72     }
73 }
74 
baseDestroy()75 void PlayerBase::baseDestroy() {
76     serviceReleasePlayer();
77     if (mAudioManager != 0) {
78         mAudioManager.clear();
79     }
80 }
81 
82 //------------------------------------------------------------------------------
servicePlayerEvent(player_state_t event,audio_port_handle_t deviceId)83 void PlayerBase::servicePlayerEvent(player_state_t event, audio_port_handle_t deviceId) {
84     if (mAudioManager != 0) {
85         bool changed = false;
86         {
87             Mutex::Autolock _l(mDeviceIdLock);
88             changed = mLastReportedDeviceId != deviceId;
89             mLastReportedDeviceId = deviceId;
90         }
91 
92         {
93             Mutex::Autolock _l(mPlayerStateLock);
94             // PLAYER_UPDATE_DEVICE_ID is not saved as an actual state, instead it is used to update
95             // device ID only.
96             if ((event != PLAYER_UPDATE_DEVICE_ID) && (event != mLastReportedEvent)) {
97                 mLastReportedEvent = event;
98                 changed = true;
99             }
100         }
101         if (changed && (mPIId != PLAYER_PIID_INVALID)) {
102             mAudioManager->playerEvent(mPIId, event, deviceId);
103         }
104     }
105 }
106 
serviceReleasePlayer()107 void PlayerBase::serviceReleasePlayer() {
108     if (mAudioManager != 0
109             && mPIId != PLAYER_PIID_INVALID) {
110         mAudioManager->releasePlayer(mPIId);
111     }
112 }
113 
114 //FIXME temporary method while some player state is outside of this class
reportEvent(player_state_t event,audio_port_handle_t deviceId)115 void PlayerBase::reportEvent(player_state_t event, audio_port_handle_t deviceId) {
116     servicePlayerEvent(event, deviceId);
117 }
118 
baseUpdateDeviceId(audio_port_handle_t deviceId)119 void PlayerBase::baseUpdateDeviceId(audio_port_handle_t deviceId) {
120     servicePlayerEvent(PLAYER_UPDATE_DEVICE_ID, deviceId);
121 }
122 
startWithStatus(audio_port_handle_t deviceId)123 status_t PlayerBase::startWithStatus(audio_port_handle_t deviceId) {
124     status_t status = playerStart();
125     if (status == NO_ERROR) {
126         servicePlayerEvent(PLAYER_STATE_STARTED, deviceId);
127     } else {
128         ALOGW("PlayerBase::start() error %d", status);
129     }
130     return status;
131 }
132 
pauseWithStatus()133 status_t PlayerBase::pauseWithStatus() {
134     status_t status = playerPause();
135     if (status == NO_ERROR) {
136         servicePlayerEvent(PLAYER_STATE_PAUSED, AUDIO_PORT_HANDLE_NONE);
137     } else {
138         ALOGW("PlayerBase::pause() error %d", status);
139     }
140     return status;
141 }
142 
stopWithStatus()143 status_t PlayerBase::stopWithStatus() {
144     status_t status = playerStop();
145 
146     if (status == NO_ERROR) {
147         servicePlayerEvent(PLAYER_STATE_STOPPED, AUDIO_PORT_HANDLE_NONE);
148     } else {
149         ALOGW("PlayerBase::stop() error %d", status);
150     }
151     return status;
152 }
153 
154 //------------------------------------------------------------------------------
155 // Implementation of IPlayer
start()156 binder::Status PlayerBase::start() {
157     ALOGD("PlayerBase::start() from IPlayer");
158     audio_port_handle_t deviceId;
159     {
160         Mutex::Autolock _l(mDeviceIdLock);
161         deviceId = mLastReportedDeviceId;
162     }
163     (void)startWithStatus(deviceId);
164     return binder::Status::ok();
165 }
166 
pause()167 binder::Status PlayerBase::pause() {
168     ALOGD("PlayerBase::pause() from IPlayer");
169     (void)pauseWithStatus();
170     return binder::Status::ok();
171 }
172 
173 
stop()174 binder::Status PlayerBase::stop() {
175     ALOGD("PlayerBase::stop() from IPlayer");
176     (void)stopWithStatus();
177     return binder::Status::ok();
178 }
179 
setVolume(float vol)180 binder::Status PlayerBase::setVolume(float vol) {
181     ALOGD("PlayerBase::setVolume() from IPlayer");
182     {
183         Mutex::Autolock _l(mSettingsLock);
184         mVolumeMultiplierL = vol;
185         mVolumeMultiplierR = vol;
186     }
187     status_t status = playerSetVolume();
188     if (status != NO_ERROR) {
189         ALOGW("PlayerBase::setVolume() error %d", status);
190     }
191     return binderStatusFromStatusT(status);
192 }
193 
setPan(float pan)194 binder::Status PlayerBase::setPan(float pan) {
195     ALOGD("PlayerBase::setPan() from IPlayer");
196     {
197         Mutex::Autolock _l(mSettingsLock);
198         pan = min(max(-1.0f, pan), 1.0f);
199         if (pan >= 0.0f) {
200             mPanMultiplierL = 1.0f - pan;
201             mPanMultiplierR = 1.0f;
202         } else {
203             mPanMultiplierL = 1.0f;
204             mPanMultiplierR = 1.0f + pan;
205         }
206     }
207     status_t status = playerSetVolume();
208     if (status != NO_ERROR) {
209         ALOGW("PlayerBase::setPan() error %d", status);
210     }
211     return binderStatusFromStatusT(status);
212 }
213 
setStartDelayMs(int32_t delayMs __unused)214 binder::Status PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
215     ALOGW("setStartDelay() is not supported");
216     return binder::Status::ok();
217 }
218 
applyVolumeShaper(const VolumeShaperConfiguration & configuration __unused,const VolumeShaperOperation & operation __unused)219 binder::Status PlayerBase::applyVolumeShaper(
220             const VolumeShaperConfiguration& configuration __unused,
221             const VolumeShaperOperation& operation __unused) {
222     ALOGW("applyVolumeShaper() is not supported");
223     return binder::Status::ok();
224 }
225 
226 } // namespace android
227