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