xref: /aosp_15_r20/frameworks/av/services/oboeservice/AAudioEndpointManager.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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