Home | History | Annotate | Download | only in oboeservice
      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