• 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 
baseDestroy()61 void PlayerBase::baseDestroy() {
62     serviceReleasePlayer();
63     if (mAudioManager != 0) {
64         mAudioManager.clear();
65     }
66 }
67 
68 //------------------------------------------------------------------------------
servicePlayerEvent(player_state_t event,audio_port_handle_t deviceId)69 void PlayerBase::servicePlayerEvent(player_state_t event, audio_port_handle_t deviceId) {
70     if (mAudioManager != 0) {
71         bool changed = false;
72         {
73             Mutex::Autolock _l(mDeviceIdLock);
74             changed = mLastReportedDeviceId != deviceId;
75             mLastReportedDeviceId = deviceId;
76         }
77 
78         {
79             Mutex::Autolock _l(mPlayerStateLock);
80             // PLAYER_UPDATE_DEVICE_ID is not saved as an actual state, instead it is used to update
81             // device ID only.
82             if ((event != PLAYER_UPDATE_DEVICE_ID) && (event != mLastReportedEvent)) {
83                 mLastReportedEvent = event;
84                 changed = true;
85             }
86         }
87         if (changed && (mPIId != PLAYER_PIID_INVALID)) {
88             mAudioManager->playerEvent(mPIId, event, deviceId);
89         }
90     }
91 }
92 
serviceReleasePlayer()93 void PlayerBase::serviceReleasePlayer() {
94     if (mAudioManager != 0
95             && mPIId != PLAYER_PIID_INVALID) {
96         mAudioManager->releasePlayer(mPIId);
97     }
98 }
99 
100 //FIXME temporary method while some player state is outside of this class
reportEvent(player_state_t event,audio_port_handle_t deviceId)101 void PlayerBase::reportEvent(player_state_t event, audio_port_handle_t deviceId) {
102     servicePlayerEvent(event, deviceId);
103 }
104 
baseUpdateDeviceId(audio_port_handle_t deviceId)105 void PlayerBase::baseUpdateDeviceId(audio_port_handle_t deviceId) {
106     servicePlayerEvent(PLAYER_UPDATE_DEVICE_ID, deviceId);
107 }
108 
startWithStatus(audio_port_handle_t deviceId)109 status_t PlayerBase::startWithStatus(audio_port_handle_t deviceId) {
110     status_t status = playerStart();
111     if (status == NO_ERROR) {
112         servicePlayerEvent(PLAYER_STATE_STARTED, deviceId);
113     } else {
114         ALOGW("PlayerBase::start() error %d", status);
115     }
116     return status;
117 }
118 
pauseWithStatus()119 status_t PlayerBase::pauseWithStatus() {
120     status_t status = playerPause();
121     if (status == NO_ERROR) {
122         servicePlayerEvent(PLAYER_STATE_PAUSED, AUDIO_PORT_HANDLE_NONE);
123     } else {
124         ALOGW("PlayerBase::pause() error %d", status);
125     }
126     return status;
127 }
128 
stopWithStatus()129 status_t PlayerBase::stopWithStatus() {
130     status_t status = playerStop();
131 
132     if (status == NO_ERROR) {
133         servicePlayerEvent(PLAYER_STATE_STOPPED, AUDIO_PORT_HANDLE_NONE);
134     } else {
135         ALOGW("PlayerBase::stop() error %d", status);
136     }
137     return status;
138 }
139 
140 //------------------------------------------------------------------------------
141 // Implementation of IPlayer
start()142 binder::Status PlayerBase::start() {
143     ALOGD("PlayerBase::start() from IPlayer");
144     audio_port_handle_t deviceId;
145     {
146         Mutex::Autolock _l(mDeviceIdLock);
147         deviceId = mLastReportedDeviceId;
148     }
149     (void)startWithStatus(deviceId);
150     return binder::Status::ok();
151 }
152 
pause()153 binder::Status PlayerBase::pause() {
154     ALOGD("PlayerBase::pause() from IPlayer");
155     (void)pauseWithStatus();
156     return binder::Status::ok();
157 }
158 
159 
stop()160 binder::Status PlayerBase::stop() {
161     ALOGD("PlayerBase::stop() from IPlayer");
162     (void)stopWithStatus();
163     return binder::Status::ok();
164 }
165 
setVolume(float vol)166 binder::Status PlayerBase::setVolume(float vol) {
167     ALOGD("PlayerBase::setVolume() from IPlayer");
168     {
169         Mutex::Autolock _l(mSettingsLock);
170         mVolumeMultiplierL = vol;
171         mVolumeMultiplierR = vol;
172     }
173     status_t status = playerSetVolume();
174     if (status != NO_ERROR) {
175         ALOGW("PlayerBase::setVolume() error %d", status);
176     }
177     return binderStatusFromStatusT(status);
178 }
179 
setPan(float pan)180 binder::Status PlayerBase::setPan(float pan) {
181     ALOGD("PlayerBase::setPan() from IPlayer");
182     {
183         Mutex::Autolock _l(mSettingsLock);
184         pan = min(max(-1.0f, pan), 1.0f);
185         if (pan >= 0.0f) {
186             mPanMultiplierL = 1.0f - pan;
187             mPanMultiplierR = 1.0f;
188         } else {
189             mPanMultiplierL = 1.0f;
190             mPanMultiplierR = 1.0f + pan;
191         }
192     }
193     status_t status = playerSetVolume();
194     if (status != NO_ERROR) {
195         ALOGW("PlayerBase::setPan() error %d", status);
196     }
197     return binderStatusFromStatusT(status);
198 }
199 
setStartDelayMs(int32_t delayMs __unused)200 binder::Status PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
201     ALOGW("setStartDelay() is not supported");
202     return binder::Status::ok();
203 }
204 
applyVolumeShaper(const VolumeShaperConfiguration & configuration __unused,const VolumeShaperOperation & operation __unused)205 binder::Status PlayerBase::applyVolumeShaper(
206             const VolumeShaperConfiguration& configuration __unused,
207             const VolumeShaperOperation& operation __unused) {
208     ALOGW("applyVolumeShaper() is not supported");
209     return binder::Status::ok();
210 }
211 
212 } // namespace android
213