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 #define LOG_TAG "AAudioServiceEndpoint" 18 //#define LOG_NDEBUG 0 19 #include <utils/Log.h> 20 21 #include <algorithm> 22 #include <assert.h> 23 #include <map> 24 #include <mutex> 25 #include <sstream> 26 #include <vector> 27 28 #include <utils/Singleton.h> 29 30 #include "AAudioEndpointManager.h" 31 #include "AAudioServiceEndpoint.h" 32 33 #include "core/AudioStreamBuilder.h" 34 #include "AAudioServiceEndpoint.h" 35 #include "AAudioServiceStreamShared.h" 36 #include "AAudioServiceEndpointShared.h" 37 38 using namespace android; // TODO just import names needed 39 using namespace aaudio; // TODO just import names needed 40 41 AAudioServiceEndpoint::~AAudioServiceEndpoint() { 42 ALOGD("AAudioServiceEndpoint::~AAudioServiceEndpoint() destroying endpoint %p", this); 43 } 44 45 std::string AAudioServiceEndpoint::dump() const { 46 std::stringstream result; 47 48 const bool isLocked = AAudio_tryUntilTrue( 49 [this]()->bool { return mLockStreams.try_lock(); } /* f */, 50 50 /* times */, 51 20 /* sleepMs */); 52 if (!isLocked) { 53 result << "AAudioServiceEndpoint may be deadlocked\n"; 54 } 55 56 result << " Direction: " << ((getDirection() == AAUDIO_DIRECTION_OUTPUT) 57 ? "OUTPUT" : "INPUT") << "\n"; 58 result << " Sample Rate: " << getSampleRate() << "\n"; 59 result << " Frames Per Burst: " << mFramesPerBurst << "\n"; 60 result << " Reference Count: " << mOpenCount << "\n"; 61 result << " Requested Device Id: " << mRequestedDeviceId << "\n"; 62 result << " Device Id: " << getDeviceId() << "\n"; 63 result << " Registered Streams:" << "\n"; 64 result << AAudioServiceStreamShared::dumpHeader() << "\n"; 65 for (const auto stream : mRegisteredStreams) { 66 result << stream->dump() << "\n"; 67 } 68 69 if (isLocked) { 70 mLockStreams.unlock(); 71 } 72 return result.str(); 73 } 74 75 void AAudioServiceEndpoint::disconnectRegisteredStreams() { 76 std::lock_guard<std::mutex> lock(mLockStreams); 77 for (const auto stream : mRegisteredStreams) { 78 stream->stop(); 79 stream->disconnect(); 80 } 81 mRegisteredStreams.clear(); 82 } 83 84 aaudio_result_t AAudioServiceEndpoint::registerStream(sp<AAudioServiceStreamBase>stream) { 85 std::lock_guard<std::mutex> lock(mLockStreams); 86 mRegisteredStreams.push_back(stream); 87 return AAUDIO_OK; 88 } 89 90 aaudio_result_t AAudioServiceEndpoint::unregisterStream(sp<AAudioServiceStreamBase>stream) { 91 std::lock_guard<std::mutex> lock(mLockStreams); 92 mRegisteredStreams.erase(std::remove( 93 mRegisteredStreams.begin(), mRegisteredStreams.end(), stream), 94 mRegisteredStreams.end()); 95 return AAUDIO_OK; 96 } 97 98 bool AAudioServiceEndpoint::matches(const AAudioStreamConfiguration& configuration) { 99 if (configuration.getDirection() != getDirection()) { 100 return false; 101 } 102 if (configuration.getDeviceId() != AAUDIO_UNSPECIFIED && 103 configuration.getDeviceId() != getDeviceId()) { 104 return false; 105 } 106 if (configuration.getSampleRate() != AAUDIO_UNSPECIFIED && 107 configuration.getSampleRate() != getSampleRate()) { 108 return false; 109 } 110 if (configuration.getSamplesPerFrame() != AAUDIO_UNSPECIFIED && 111 configuration.getSamplesPerFrame() != getSamplesPerFrame()) { 112 return false; 113 } 114 return true; 115 } 116