1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AAudioEndpointManager"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include <assert.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <functional>
23*ec779b8eSAndroid Build Coastguard Worker #include <map>
24*ec779b8eSAndroid Build Coastguard Worker #include <mutex>
25*ec779b8eSAndroid Build Coastguard Worker #include <sstream>
26*ec779b8eSAndroid Build Coastguard Worker #include <utility/AAudioUtilities.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversion.h>
28*ec779b8eSAndroid Build Coastguard Worker
29*ec779b8eSAndroid Build Coastguard Worker #include "AAudioClientTracker.h"
30*ec779b8eSAndroid Build Coastguard Worker #include "AAudioEndpointManager.h"
31*ec779b8eSAndroid Build Coastguard Worker #include "AAudioServiceEndpointShared.h"
32*ec779b8eSAndroid Build Coastguard Worker #include "AAudioServiceEndpointMMAP.h"
33*ec779b8eSAndroid Build Coastguard Worker #include "AAudioServiceEndpointCapture.h"
34*ec779b8eSAndroid Build Coastguard Worker #include "AAudioServiceEndpointPlay.h"
35*ec779b8eSAndroid Build Coastguard Worker
36*ec779b8eSAndroid Build Coastguard Worker using namespace android;
37*ec779b8eSAndroid Build Coastguard Worker using namespace aaudio;
38*ec779b8eSAndroid Build Coastguard Worker
39*ec779b8eSAndroid Build Coastguard Worker ANDROID_SINGLETON_STATIC_INSTANCE(AAudioEndpointManager);
40*ec779b8eSAndroid Build Coastguard Worker
AAudioEndpointManager()41*ec779b8eSAndroid Build Coastguard Worker AAudioEndpointManager::AAudioEndpointManager()
42*ec779b8eSAndroid Build Coastguard Worker : Singleton<AAudioEndpointManager>()
43*ec779b8eSAndroid Build Coastguard Worker , mSharedStreams()
44*ec779b8eSAndroid Build Coastguard Worker , mExclusiveStreams() {
45*ec779b8eSAndroid Build Coastguard Worker }
46*ec779b8eSAndroid Build Coastguard Worker
dump() const47*ec779b8eSAndroid Build Coastguard Worker std::string AAudioEndpointManager::dump() const NO_THREAD_SAFETY_ANALYSIS {
48*ec779b8eSAndroid Build Coastguard Worker std::stringstream result;
49*ec779b8eSAndroid Build Coastguard Worker int index = 0;
50*ec779b8eSAndroid Build Coastguard Worker
51*ec779b8eSAndroid Build Coastguard Worker result << "AAudioEndpointManager:" << "\n";
52*ec779b8eSAndroid Build Coastguard Worker
53*ec779b8eSAndroid Build Coastguard Worker const bool isSharedLocked = AAudio_tryUntilTrue(
54*ec779b8eSAndroid Build Coastguard Worker [this]()->bool { return mSharedLock.try_lock(); } /* f */,
55*ec779b8eSAndroid Build Coastguard Worker 50 /* times */,
56*ec779b8eSAndroid Build Coastguard Worker 20 /* sleepMs */);
57*ec779b8eSAndroid Build Coastguard Worker if (!isSharedLocked) {
58*ec779b8eSAndroid Build Coastguard Worker result << "AAudioEndpointManager Shared may be deadlocked\n";
59*ec779b8eSAndroid Build Coastguard Worker }
60*ec779b8eSAndroid Build Coastguard Worker
61*ec779b8eSAndroid Build Coastguard Worker {
62*ec779b8eSAndroid Build Coastguard Worker const bool isExclusiveLocked = AAudio_tryUntilTrue(
63*ec779b8eSAndroid Build Coastguard Worker [this]() -> bool { return mExclusiveLock.try_lock(); } /* f */,
64*ec779b8eSAndroid Build Coastguard Worker 50 /* times */,
65*ec779b8eSAndroid Build Coastguard Worker 20 /* sleepMs */);
66*ec779b8eSAndroid Build Coastguard Worker if (!isExclusiveLocked) {
67*ec779b8eSAndroid Build Coastguard Worker result << "AAudioEndpointManager Exclusive may be deadlocked\n";
68*ec779b8eSAndroid Build Coastguard Worker }
69*ec779b8eSAndroid Build Coastguard Worker
70*ec779b8eSAndroid Build Coastguard Worker result << "Exclusive MMAP Endpoints: " << mExclusiveStreams.size() << "\n";
71*ec779b8eSAndroid Build Coastguard Worker index = 0;
72*ec779b8eSAndroid Build Coastguard Worker for (const auto &stream : mExclusiveStreams) {
73*ec779b8eSAndroid Build Coastguard Worker result << " #" << index++ << ":";
74*ec779b8eSAndroid Build Coastguard Worker result << stream->dump() << "\n";
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker
77*ec779b8eSAndroid Build Coastguard Worker result << " ExclusiveSearchCount: " << mExclusiveSearchCount << "\n";
78*ec779b8eSAndroid Build Coastguard Worker result << " ExclusiveFoundCount: " << mExclusiveFoundCount << "\n";
79*ec779b8eSAndroid Build Coastguard Worker result << " ExclusiveOpenCount: " << mExclusiveOpenCount << "\n";
80*ec779b8eSAndroid Build Coastguard Worker result << " ExclusiveCloseCount: " << mExclusiveCloseCount << "\n";
81*ec779b8eSAndroid Build Coastguard Worker result << " ExclusiveStolenCount: " << mExclusiveStolenCount << "\n";
82*ec779b8eSAndroid Build Coastguard Worker result << "\n";
83*ec779b8eSAndroid Build Coastguard Worker
84*ec779b8eSAndroid Build Coastguard Worker if (isExclusiveLocked) {
85*ec779b8eSAndroid Build Coastguard Worker mExclusiveLock.unlock();
86*ec779b8eSAndroid Build Coastguard Worker }
87*ec779b8eSAndroid Build Coastguard Worker }
88*ec779b8eSAndroid Build Coastguard Worker
89*ec779b8eSAndroid Build Coastguard Worker result << "Shared Endpoints: " << mSharedStreams.size() << "\n";
90*ec779b8eSAndroid Build Coastguard Worker index = 0;
91*ec779b8eSAndroid Build Coastguard Worker for (const auto &stream : mSharedStreams) {
92*ec779b8eSAndroid Build Coastguard Worker result << " #" << index++ << ":";
93*ec779b8eSAndroid Build Coastguard Worker result << stream->dump() << "\n";
94*ec779b8eSAndroid Build Coastguard Worker }
95*ec779b8eSAndroid Build Coastguard Worker
96*ec779b8eSAndroid Build Coastguard Worker result << " SharedSearchCount: " << mSharedSearchCount << "\n";
97*ec779b8eSAndroid Build Coastguard Worker result << " SharedFoundCount: " << mSharedFoundCount << "\n";
98*ec779b8eSAndroid Build Coastguard Worker result << " SharedOpenCount: " << mSharedOpenCount << "\n";
99*ec779b8eSAndroid Build Coastguard Worker result << " SharedCloseCount: " << mSharedCloseCount << "\n";
100*ec779b8eSAndroid Build Coastguard Worker result << "\n";
101*ec779b8eSAndroid Build Coastguard Worker
102*ec779b8eSAndroid Build Coastguard Worker if (isSharedLocked) {
103*ec779b8eSAndroid Build Coastguard Worker mSharedLock.unlock();
104*ec779b8eSAndroid Build Coastguard Worker }
105*ec779b8eSAndroid Build Coastguard Worker return result.str();
106*ec779b8eSAndroid Build Coastguard Worker }
107*ec779b8eSAndroid Build Coastguard Worker
108*ec779b8eSAndroid Build Coastguard Worker
109*ec779b8eSAndroid Build Coastguard Worker // Try to find an existing endpoint.
findExclusiveEndpoint_l(const AAudioStreamConfiguration & configuration)110*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> AAudioEndpointManager::findExclusiveEndpoint_l(
111*ec779b8eSAndroid Build Coastguard Worker const AAudioStreamConfiguration &configuration) {
112*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> endpoint;
113*ec779b8eSAndroid Build Coastguard Worker mExclusiveSearchCount++;
114*ec779b8eSAndroid Build Coastguard Worker for (const auto& ep : mExclusiveStreams) {
115*ec779b8eSAndroid Build Coastguard Worker if (ep->matches(configuration)) {
116*ec779b8eSAndroid Build Coastguard Worker mExclusiveFoundCount++;
117*ec779b8eSAndroid Build Coastguard Worker endpoint = ep;
118*ec779b8eSAndroid Build Coastguard Worker break;
119*ec779b8eSAndroid Build Coastguard Worker }
120*ec779b8eSAndroid Build Coastguard Worker }
121*ec779b8eSAndroid Build Coastguard Worker
122*ec779b8eSAndroid Build Coastguard Worker ALOGV("findExclusiveEndpoint_l(), found %p for devices = %s, sessionId = %d",
123*ec779b8eSAndroid Build Coastguard Worker endpoint.get(), toString(configuration.getDeviceIds()).c_str(),
124*ec779b8eSAndroid Build Coastguard Worker configuration.getSessionId());
125*ec779b8eSAndroid Build Coastguard Worker return endpoint;
126*ec779b8eSAndroid Build Coastguard Worker }
127*ec779b8eSAndroid Build Coastguard Worker
128*ec779b8eSAndroid Build Coastguard Worker // Try to find an existing endpoint.
findSharedEndpoint_l(const AAudioStreamConfiguration & configuration)129*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpointShared> AAudioEndpointManager::findSharedEndpoint_l(
130*ec779b8eSAndroid Build Coastguard Worker const AAudioStreamConfiguration &configuration) {
131*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpointShared> endpoint;
132*ec779b8eSAndroid Build Coastguard Worker mSharedSearchCount++;
133*ec779b8eSAndroid Build Coastguard Worker for (const auto& ep : mSharedStreams) {
134*ec779b8eSAndroid Build Coastguard Worker if (ep->matches(configuration)) {
135*ec779b8eSAndroid Build Coastguard Worker mSharedFoundCount++;
136*ec779b8eSAndroid Build Coastguard Worker endpoint = ep;
137*ec779b8eSAndroid Build Coastguard Worker break;
138*ec779b8eSAndroid Build Coastguard Worker }
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker
141*ec779b8eSAndroid Build Coastguard Worker ALOGV("findSharedEndpoint_l(), found %p for devices = %s, sessionId = %d",
142*ec779b8eSAndroid Build Coastguard Worker endpoint.get(), toString(configuration.getDeviceIds()).c_str(),
143*ec779b8eSAndroid Build Coastguard Worker configuration.getSessionId());
144*ec779b8eSAndroid Build Coastguard Worker return endpoint;
145*ec779b8eSAndroid Build Coastguard Worker }
146*ec779b8eSAndroid Build Coastguard Worker
openEndpoint(AAudioService & audioService,const aaudio::AAudioStreamRequest & request)147*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> AAudioEndpointManager::openEndpoint(AAudioService &audioService,
148*ec779b8eSAndroid Build Coastguard Worker const aaudio::AAudioStreamRequest &request) {
149*ec779b8eSAndroid Build Coastguard Worker if (request.getConstantConfiguration().getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
150*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> endpointToSteal;
151*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> foundEndpoint =
152*ec779b8eSAndroid Build Coastguard Worker openExclusiveEndpoint(audioService, request, endpointToSteal);
153*ec779b8eSAndroid Build Coastguard Worker if (endpointToSteal.get()) {
154*ec779b8eSAndroid Build Coastguard Worker endpointToSteal->releaseRegisteredStreams(); // free the MMAP resource
155*ec779b8eSAndroid Build Coastguard Worker }
156*ec779b8eSAndroid Build Coastguard Worker return foundEndpoint;
157*ec779b8eSAndroid Build Coastguard Worker } else {
158*ec779b8eSAndroid Build Coastguard Worker return openSharedEndpoint(audioService, request);
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker }
161*ec779b8eSAndroid Build Coastguard Worker
openExclusiveEndpoint(AAudioService & aaudioService,const aaudio::AAudioStreamRequest & request,sp<AAudioServiceEndpoint> & endpointToSteal)162*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> AAudioEndpointManager::openExclusiveEndpoint(
163*ec779b8eSAndroid Build Coastguard Worker AAudioService &aaudioService,
164*ec779b8eSAndroid Build Coastguard Worker const aaudio::AAudioStreamRequest &request,
165*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> &endpointToSteal) {
166*ec779b8eSAndroid Build Coastguard Worker
167*ec779b8eSAndroid Build Coastguard Worker const std::lock_guard<std::mutex> lock(mExclusiveLock);
168*ec779b8eSAndroid Build Coastguard Worker
169*ec779b8eSAndroid Build Coastguard Worker const AAudioStreamConfiguration &configuration = request.getConstantConfiguration();
170*ec779b8eSAndroid Build Coastguard Worker
171*ec779b8eSAndroid Build Coastguard Worker // Try to find an existing endpoint.
172*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> endpoint = findExclusiveEndpoint_l(configuration);
173*ec779b8eSAndroid Build Coastguard Worker
174*ec779b8eSAndroid Build Coastguard Worker // If we find an existing one then this one cannot be exclusive.
175*ec779b8eSAndroid Build Coastguard Worker if (endpoint.get() != nullptr) {
176*ec779b8eSAndroid Build Coastguard Worker if (kStealingEnabled
177*ec779b8eSAndroid Build Coastguard Worker && !endpoint->isForSharing() // not currently SHARED
178*ec779b8eSAndroid Build Coastguard Worker && !request.isSharingModeMatchRequired()) { // app did not request a shared stream
179*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s() endpoint in EXCLUSIVE use. Steal it!", __func__);
180*ec779b8eSAndroid Build Coastguard Worker mExclusiveStolenCount++;
181*ec779b8eSAndroid Build Coastguard Worker // Prevent this process from getting another EXCLUSIVE stream.
182*ec779b8eSAndroid Build Coastguard Worker // This will prevent two clients from colliding after a DISCONNECTION
183*ec779b8eSAndroid Build Coastguard Worker // when they both try to open an exclusive stream at the same time.
184*ec779b8eSAndroid Build Coastguard Worker // That can result in a stream getting disconnected between the OPEN
185*ec779b8eSAndroid Build Coastguard Worker // and START calls. This will help preserve app compatibility.
186*ec779b8eSAndroid Build Coastguard Worker // An app can avoid having this happen by closing their streams when
187*ec779b8eSAndroid Build Coastguard Worker // the app is paused.
188*ec779b8eSAndroid Build Coastguard Worker const pid_t pid = VALUE_OR_FATAL(
189*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_int32_t_pid_t(request.getAttributionSource().pid));
190*ec779b8eSAndroid Build Coastguard Worker AAudioClientTracker::getInstance().setExclusiveEnabled(pid, false);
191*ec779b8eSAndroid Build Coastguard Worker endpointToSteal = endpoint; // return it to caller
192*ec779b8eSAndroid Build Coastguard Worker }
193*ec779b8eSAndroid Build Coastguard Worker return nullptr;
194*ec779b8eSAndroid Build Coastguard Worker } else {
195*ec779b8eSAndroid Build Coastguard Worker const sp<AAudioServiceEndpointMMAP> endpointMMap =
196*ec779b8eSAndroid Build Coastguard Worker new AAudioServiceEndpointMMAP(aaudioService);
197*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s(), no match so try to open MMAP %p for devices %s",
198*ec779b8eSAndroid Build Coastguard Worker __func__, endpointMMap.get(), toString(configuration.getDeviceIds()).c_str());
199*ec779b8eSAndroid Build Coastguard Worker endpoint = endpointMMap;
200*ec779b8eSAndroid Build Coastguard Worker
201*ec779b8eSAndroid Build Coastguard Worker const aaudio_result_t result = endpoint->open(request);
202*ec779b8eSAndroid Build Coastguard Worker if (result != AAUDIO_OK) {
203*ec779b8eSAndroid Build Coastguard Worker endpoint.clear();
204*ec779b8eSAndroid Build Coastguard Worker } else {
205*ec779b8eSAndroid Build Coastguard Worker mExclusiveStreams.push_back(endpointMMap);
206*ec779b8eSAndroid Build Coastguard Worker mExclusiveOpenCount++;
207*ec779b8eSAndroid Build Coastguard Worker }
208*ec779b8eSAndroid Build Coastguard Worker }
209*ec779b8eSAndroid Build Coastguard Worker
210*ec779b8eSAndroid Build Coastguard Worker if (endpoint.get() != nullptr) {
211*ec779b8eSAndroid Build Coastguard Worker // Increment the reference count under this lock.
212*ec779b8eSAndroid Build Coastguard Worker endpoint->setOpenCount(endpoint->getOpenCount() + 1);
213*ec779b8eSAndroid Build Coastguard Worker endpoint->setForSharing(request.isSharingModeMatchRequired());
214*ec779b8eSAndroid Build Coastguard Worker }
215*ec779b8eSAndroid Build Coastguard Worker
216*ec779b8eSAndroid Build Coastguard Worker return endpoint;
217*ec779b8eSAndroid Build Coastguard Worker }
218*ec779b8eSAndroid Build Coastguard Worker
openSharedEndpoint(AAudioService & aaudioService,const aaudio::AAudioStreamRequest & request)219*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpoint> AAudioEndpointManager::openSharedEndpoint(
220*ec779b8eSAndroid Build Coastguard Worker AAudioService &aaudioService,
221*ec779b8eSAndroid Build Coastguard Worker const aaudio::AAudioStreamRequest &request) {
222*ec779b8eSAndroid Build Coastguard Worker
223*ec779b8eSAndroid Build Coastguard Worker const std::lock_guard<std::mutex> lock(mSharedLock);
224*ec779b8eSAndroid Build Coastguard Worker
225*ec779b8eSAndroid Build Coastguard Worker const AAudioStreamConfiguration &configuration = request.getConstantConfiguration();
226*ec779b8eSAndroid Build Coastguard Worker const aaudio_direction_t direction = configuration.getDirection();
227*ec779b8eSAndroid Build Coastguard Worker
228*ec779b8eSAndroid Build Coastguard Worker // Try to find an existing endpoint.
229*ec779b8eSAndroid Build Coastguard Worker sp<AAudioServiceEndpointShared> endpoint = findSharedEndpoint_l(configuration);
230*ec779b8eSAndroid Build Coastguard Worker
231*ec779b8eSAndroid Build Coastguard Worker // If we can't find an existing one then open a new one.
232*ec779b8eSAndroid Build Coastguard Worker if (endpoint.get() == nullptr) {
233*ec779b8eSAndroid Build Coastguard Worker // we must call openStream with audioserver identity
234*ec779b8eSAndroid Build Coastguard Worker const int64_t token = IPCThreadState::self()->clearCallingIdentity();
235*ec779b8eSAndroid Build Coastguard Worker switch (direction) {
236*ec779b8eSAndroid Build Coastguard Worker case AAUDIO_DIRECTION_INPUT:
237*ec779b8eSAndroid Build Coastguard Worker endpoint = new AAudioServiceEndpointCapture(aaudioService);
238*ec779b8eSAndroid Build Coastguard Worker break;
239*ec779b8eSAndroid Build Coastguard Worker case AAUDIO_DIRECTION_OUTPUT:
240*ec779b8eSAndroid Build Coastguard Worker endpoint = new AAudioServiceEndpointPlay(aaudioService);
241*ec779b8eSAndroid Build Coastguard Worker break;
242*ec779b8eSAndroid Build Coastguard Worker default:
243*ec779b8eSAndroid Build Coastguard Worker break;
244*ec779b8eSAndroid Build Coastguard Worker }
245*ec779b8eSAndroid Build Coastguard Worker
246*ec779b8eSAndroid Build Coastguard Worker if (endpoint.get() != nullptr) {
247*ec779b8eSAndroid Build Coastguard Worker const aaudio_result_t result = endpoint->open(request);
248*ec779b8eSAndroid Build Coastguard Worker if (result != AAUDIO_OK) {
249*ec779b8eSAndroid Build Coastguard Worker endpoint.clear();
250*ec779b8eSAndroid Build Coastguard Worker } else {
251*ec779b8eSAndroid Build Coastguard Worker mSharedStreams.push_back(endpoint);
252*ec779b8eSAndroid Build Coastguard Worker mSharedOpenCount++;
253*ec779b8eSAndroid Build Coastguard Worker }
254*ec779b8eSAndroid Build Coastguard Worker }
255*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s(), created endpoint %p, requested device = %s, dir = %d",
256*ec779b8eSAndroid Build Coastguard Worker __func__, endpoint.get(), android::toString(configuration.getDeviceIds()).c_str(),
257*ec779b8eSAndroid Build Coastguard Worker (int)direction);
258*ec779b8eSAndroid Build Coastguard Worker IPCThreadState::self()->restoreCallingIdentity(token);
259*ec779b8eSAndroid Build Coastguard Worker }
260*ec779b8eSAndroid Build Coastguard Worker
261*ec779b8eSAndroid Build Coastguard Worker if (endpoint.get() != nullptr) {
262*ec779b8eSAndroid Build Coastguard Worker // Increment the reference count under this lock.
263*ec779b8eSAndroid Build Coastguard Worker endpoint->setOpenCount(endpoint->getOpenCount() + 1);
264*ec779b8eSAndroid Build Coastguard Worker }
265*ec779b8eSAndroid Build Coastguard Worker return endpoint;
266*ec779b8eSAndroid Build Coastguard Worker }
267*ec779b8eSAndroid Build Coastguard Worker
closeEndpoint(const sp<AAudioServiceEndpoint> & serviceEndpoint)268*ec779b8eSAndroid Build Coastguard Worker void AAudioEndpointManager::closeEndpoint(const sp<AAudioServiceEndpoint>& serviceEndpoint) {
269*ec779b8eSAndroid Build Coastguard Worker if (serviceEndpoint->getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
270*ec779b8eSAndroid Build Coastguard Worker return closeExclusiveEndpoint(serviceEndpoint);
271*ec779b8eSAndroid Build Coastguard Worker } else {
272*ec779b8eSAndroid Build Coastguard Worker return closeSharedEndpoint(serviceEndpoint);
273*ec779b8eSAndroid Build Coastguard Worker }
274*ec779b8eSAndroid Build Coastguard Worker }
275*ec779b8eSAndroid Build Coastguard Worker
closeExclusiveEndpoint(const sp<AAudioServiceEndpoint> & serviceEndpoint)276*ec779b8eSAndroid Build Coastguard Worker void AAudioEndpointManager::closeExclusiveEndpoint(
277*ec779b8eSAndroid Build Coastguard Worker const sp<AAudioServiceEndpoint>& serviceEndpoint) {
278*ec779b8eSAndroid Build Coastguard Worker if (serviceEndpoint.get() == nullptr) {
279*ec779b8eSAndroid Build Coastguard Worker return;
280*ec779b8eSAndroid Build Coastguard Worker }
281*ec779b8eSAndroid Build Coastguard Worker
282*ec779b8eSAndroid Build Coastguard Worker // Decrement the reference count under this lock.
283*ec779b8eSAndroid Build Coastguard Worker const std::lock_guard<std::mutex> lock(mExclusiveLock);
284*ec779b8eSAndroid Build Coastguard Worker const int32_t newRefCount = serviceEndpoint->getOpenCount() - 1;
285*ec779b8eSAndroid Build Coastguard Worker serviceEndpoint->setOpenCount(newRefCount);
286*ec779b8eSAndroid Build Coastguard Worker
287*ec779b8eSAndroid Build Coastguard Worker // If no longer in use then actually close it.
288*ec779b8eSAndroid Build Coastguard Worker if (newRefCount <= 0) {
289*ec779b8eSAndroid Build Coastguard Worker mExclusiveStreams.erase(
290*ec779b8eSAndroid Build Coastguard Worker std::remove(mExclusiveStreams.begin(), mExclusiveStreams.end(), serviceEndpoint),
291*ec779b8eSAndroid Build Coastguard Worker mExclusiveStreams.end());
292*ec779b8eSAndroid Build Coastguard Worker
293*ec779b8eSAndroid Build Coastguard Worker serviceEndpoint->close();
294*ec779b8eSAndroid Build Coastguard Worker mExclusiveCloseCount++;
295*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s() %p for devices %s",
296*ec779b8eSAndroid Build Coastguard Worker __func__, serviceEndpoint.get(),
297*ec779b8eSAndroid Build Coastguard Worker android::toString(serviceEndpoint->getDeviceIds()).c_str());
298*ec779b8eSAndroid Build Coastguard Worker }
299*ec779b8eSAndroid Build Coastguard Worker }
300*ec779b8eSAndroid Build Coastguard Worker
closeSharedEndpoint(const sp<AAudioServiceEndpoint> & serviceEndpoint)301*ec779b8eSAndroid Build Coastguard Worker void AAudioEndpointManager::closeSharedEndpoint(const sp<AAudioServiceEndpoint>& serviceEndpoint) {
302*ec779b8eSAndroid Build Coastguard Worker if (serviceEndpoint.get() == nullptr) {
303*ec779b8eSAndroid Build Coastguard Worker return;
304*ec779b8eSAndroid Build Coastguard Worker }
305*ec779b8eSAndroid Build Coastguard Worker
306*ec779b8eSAndroid Build Coastguard Worker // Decrement the reference count under this lock.
307*ec779b8eSAndroid Build Coastguard Worker const std::lock_guard<std::mutex> lock(mSharedLock);
308*ec779b8eSAndroid Build Coastguard Worker const int32_t newRefCount = serviceEndpoint->getOpenCount() - 1;
309*ec779b8eSAndroid Build Coastguard Worker serviceEndpoint->setOpenCount(newRefCount);
310*ec779b8eSAndroid Build Coastguard Worker
311*ec779b8eSAndroid Build Coastguard Worker // If no longer in use then actually close it.
312*ec779b8eSAndroid Build Coastguard Worker if (newRefCount <= 0) {
313*ec779b8eSAndroid Build Coastguard Worker mSharedStreams.erase(
314*ec779b8eSAndroid Build Coastguard Worker std::remove(mSharedStreams.begin(), mSharedStreams.end(), serviceEndpoint),
315*ec779b8eSAndroid Build Coastguard Worker mSharedStreams.end());
316*ec779b8eSAndroid Build Coastguard Worker
317*ec779b8eSAndroid Build Coastguard Worker serviceEndpoint->close();
318*ec779b8eSAndroid Build Coastguard Worker
319*ec779b8eSAndroid Build Coastguard Worker mSharedCloseCount++;
320*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s(%p) closed for device %s",
321*ec779b8eSAndroid Build Coastguard Worker __func__, serviceEndpoint.get(),
322*ec779b8eSAndroid Build Coastguard Worker android::toString(serviceEndpoint->getDeviceIds()).c_str());
323*ec779b8eSAndroid Build Coastguard Worker }
324*ec779b8eSAndroid Build Coastguard Worker }
325