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 std::string AAudioServiceEndpoint::dump() const { 42 std::stringstream result; 43 44 const bool isLocked = AAudio_tryUntilTrue( 45 [this]()->bool { return mLockStreams.try_lock(); } /* f */, 46 50 /* times */, 47 20 /* sleepMs */); 48 if (!isLocked) { 49 result << "AAudioServiceEndpoint may be deadlocked\n"; 50 } 51 52 result << " Direction: " << ((getDirection() == AAUDIO_DIRECTION_OUTPUT) 53 ? "OUTPUT" : "INPUT") << "\n"; 54 result << " Requested Device Id: " << mRequestedDeviceId << "\n"; 55 result << " Device Id: " << getDeviceId() << "\n"; 56 result << " Sample Rate: " << getSampleRate() << "\n"; 57 result << " Channel Count: " << getSamplesPerFrame() << "\n"; 58 result << " Format: " << getFormat() << "\n"; 59 result << " Frames Per Burst: " << mFramesPerBurst << "\n"; 60 result << " Usage: " << getUsage() << "\n"; 61 result << " ContentType: " << getContentType() << "\n"; 62 result << " InputPreset: " << getInputPreset() << "\n"; 63 result << " Reference Count: " << mOpenCount << "\n"; 64 result << " Session Id: " << getSessionId() << "\n"; 65 result << " Connected: " << mConnected.load() << "\n"; 66 result << " Registered Streams:" << "\n"; 67 result << AAudioServiceStreamShared::dumpHeader() << "\n"; 68 for (const auto& stream : mRegisteredStreams) { 69 result << stream->dump() << "\n"; 70 } 71 72 if (isLocked) { 73 mLockStreams.unlock(); 74 } 75 return result.str(); 76 } 77 78 // @return true if stream found 79 bool AAudioServiceEndpoint::isStreamRegistered(audio_port_handle_t portHandle) { 80 std::lock_guard<std::mutex> lock(mLockStreams); 81 for (const auto& stream : mRegisteredStreams) { 82 if (stream->getPortHandle() == portHandle) { 83 return true; 84 } 85 } 86 return false; 87 } 88 89 void AAudioServiceEndpoint::disconnectRegisteredStreams() { 90 std::lock_guard<std::mutex> lock(mLockStreams); 91 mConnected.store(false); 92 for (const auto& stream : mRegisteredStreams) { 93 ALOGD("disconnectRegisteredStreams() stop and disconnect port %d", 94 stream->getPortHandle()); 95 stream->stop(); 96 stream->disconnect(); 97 } 98 mRegisteredStreams.clear(); 99 } 100 101 aaudio_result_t AAudioServiceEndpoint::registerStream(sp<AAudioServiceStreamBase>stream) { 102 std::lock_guard<std::mutex> lock(mLockStreams); 103 mRegisteredStreams.push_back(stream); 104 return AAUDIO_OK; 105 } 106 107 aaudio_result_t AAudioServiceEndpoint::unregisterStream(sp<AAudioServiceStreamBase>stream) { 108 std::lock_guard<std::mutex> lock(mLockStreams); 109 mRegisteredStreams.erase(std::remove( 110 mRegisteredStreams.begin(), mRegisteredStreams.end(), stream), 111 mRegisteredStreams.end()); 112 return AAUDIO_OK; 113 } 114 115 bool AAudioServiceEndpoint::matches(const AAudioStreamConfiguration& configuration) { 116 if (!mConnected.load()) { 117 return false; // Only use an endpoint if it is connected to a device. 118 } 119 if (configuration.getDirection() != getDirection()) { 120 return false; 121 } 122 if (configuration.getDeviceId() != AAUDIO_UNSPECIFIED && 123 configuration.getDeviceId() != getDeviceId()) { 124 return false; 125 } 126 if (configuration.getSessionId() != AAUDIO_SESSION_ID_ALLOCATE && 127 configuration.getSessionId() != getSessionId()) { 128 return false; 129 } 130 if (configuration.getSampleRate() != AAUDIO_UNSPECIFIED && 131 configuration.getSampleRate() != getSampleRate()) { 132 return false; 133 } 134 if (configuration.getSamplesPerFrame() != AAUDIO_UNSPECIFIED && 135 configuration.getSamplesPerFrame() != getSamplesPerFrame()) { 136 return false; 137 } 138 return true; 139 } 140